diff --git a/pytest_splunk_addon_ui_smartx/components/controls/file.py b/pytest_splunk_addon_ui_smartx/components/controls/file.py new file mode 100644 index 00000000..e55fe83a --- /dev/null +++ b/pytest_splunk_addon_ui_smartx/components/controls/file.py @@ -0,0 +1,94 @@ +# +# Copyright 2024 Splunk Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from ..base_component import Selector +from .base_control import BaseControl +from selenium.common.exceptions import TimeoutException + + +class File(BaseControl): + """ + Entity-Component: File + """ + + def __init__(self, browser, container) -> None: + """ + :param browser: The selenium webdriver + :param container: The locator of the container where the control is located in. + """ + super().__init__(browser, container) + self.elements.update( + { + "input": Selector(select=container.select + " input"), + "support_message": Selector( + select=container.select + + ' [data-test="file"] [data-test="file-supports"]' + ), + "error_text": Selector( + select=container.select + ' [data-test="file"] [data-test="help"]' + ), + "selected": Selector( + select=container.select + ' [data-test="item"] [data-test="label"]' + ), + "cancel_selected": Selector( + select=container.select + ' [data-test="remove"]' + ), + } + ) + + def set_value(self, value: str) -> None: + """ + set value of the File input + """ + self.wait_for("input") + self.input.send_keys(value) + + def get_value(self) -> str: + """ + get the name of the selected file + :return: Str The name of the selected file + """ + try: + return self.selected.get_attribute("innerText").strip() + except TimeoutException: + pass + return "" + + def get_support_message(self) -> str: + """ + get the file support message + :return: Str file support message + """ + return self.support_message.get_attribute("innerText").strip() + + def get_error_text(self) -> str: + """ + get the file validation error text + :return: Str error message of the file validation + """ + try: + return self.error_text.get_attribute("innerText").strip() + except TimeoutException: + pass + return "" + + def cancel_selected_value(self) -> bool: + """ + Cancels the currently selected value in the File component + :return: Bool whether canceling the selected item was successful, else raises an error + """ + self.wait_to_be_clickable("cancel_selected") + self.cancel_selected.click() + return True diff --git a/tests/testdata/Splunk_TA_UCCExample/globalConfig.json b/tests/testdata/Splunk_TA_UCCExample/globalConfig.json index 913649e7..4b8de9a4 100644 --- a/tests/testdata/Splunk_TA_UCCExample/globalConfig.json +++ b/tests/testdata/Splunk_TA_UCCExample/globalConfig.json @@ -42,6 +42,26 @@ "help": "Enter a unique name for this account.", "required": true }, + { + "type": "file", + "label": "Example File", + "help": "Upload example file", + "field": "example_file", + "options": { + "fileSupportMessage": "Example Support message", + "supportedFileTypes": ["conf", "txt"], + "maxFileSize": 1, + "useBase64Encoding": false + }, + "validators": [ + { + "type": "regex", + "pattern": "^Example*" + } + ], + "encrypted": true, + "required": true + }, { "type": "singleSelect", "label": "Example Environment", diff --git a/tests/ui/Example_UccLib/account.py b/tests/ui/Example_UccLib/account.py index a6a76051..6b2e59fc 100644 --- a/tests/ui/Example_UccLib/account.py +++ b/tests/ui/Example_UccLib/account.py @@ -9,6 +9,7 @@ from pytest_splunk_addon_ui_smartx.components.controls.multi_select import MultiSelect from pytest_splunk_addon_ui_smartx.components.controls.checkbox import Checkbox from pytest_splunk_addon_ui_smartx.components.controls.textbox import TextBox +from pytest_splunk_addon_ui_smartx.components.controls.file import File from pytest_splunk_addon_ui_smartx.components.controls.learn_more import LearnMore from pytest_splunk_addon_ui_smartx.components.controls.toggle import Toggle from pytest_splunk_addon_ui_smartx.components.controls.message import Message @@ -40,6 +41,10 @@ def __init__(self, browser, container): self.name = TextBox( browser, Selector(select='[data-test="control-group"][data-name="name"]') ) + self.file = File( + browser, + Selector(select='[data-test="control-group"][data-name="example_file"]'), + ) self.environment = SingleSelect( browser, Selector(select='[data-test="control-group"][data-name="custom_endpoint"]'), diff --git a/tests/ui/conftest.py b/tests/ui/conftest.py index fad1f817..b4b910eb 100644 --- a/tests/ui/conftest.py +++ b/tests/ui/conftest.py @@ -24,6 +24,7 @@ def add_account(ucc_smartx_rest_helper): "redirect_url": "", "endpoint": "", "example_help_link": "", + "example_file": "Example file content", } yield account.backend_conf.post_stanza(url, kwargs) account.backend_conf.delete_all_stanzas() diff --git a/tests/ui/test_splunk_ta_example_addon_account.py b/tests/ui/test_splunk_ta_example_addon_account.py index d727bca4..d079973d 100644 --- a/tests/ui/test_splunk_ta_example_addon_account.py +++ b/tests/ui/test_splunk_ta_example_addon_account.py @@ -2,12 +2,14 @@ from .Example_UccLib.account import AccountPage from .Example_UccLib.input_page import InputPage +import os import pytest import copy ACCOUNT_CONFIG = { "name": "TestAccount", + "example_file": "tests/ui/testdata/example_file.txt", "account_checkbox": 1, "account_multiple_select": "one", "account_radio": "yes", @@ -23,6 +25,10 @@ "example_help_link": "", } +INVALID_FILE = "tests/ui/testdata/invalid_file.json" +LARGE_SIZE_FILE = "tests/ui/testdata/large_file.txt" +INVALID_FILE_CONTENT = "tests/ui/testdata/invalid_file_content.conf" + @pytest.fixture def add_input(ucc_smartx_rest_helper): @@ -55,7 +61,8 @@ def add_account(ucc_smartx_rest_helper): ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False ) url = account._get_account_endpoint() - kwargs = ACCOUNT_CONFIG + kwargs = copy.deepcopy(ACCOUNT_CONFIG) + kwargs["example_file"] = "Example file content" yield account.backend_conf.post_stanza(url, kwargs) @@ -68,6 +75,7 @@ def add_multiple_account(ucc_smartx_rest_helper): for i in range(12): kwargs = copy.deepcopy(ACCOUNT_CONFIG) kwargs["name"] = kwargs["name"] + str(i) + kwargs["example_file"] = "Example file content" account.backend_conf.post_stanza(url, kwargs) @@ -81,7 +89,6 @@ def delete_accounts(ucc_smartx_rest_helper): class TestAccount(UccTester): - ############################ ### TEST CASES FOR TABLE ### ############################ @@ -365,6 +372,7 @@ def test_account_required_field_username( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.environment.select("Value2") account.entity.multiple_select.select("Option Two") account.entity.password.set_value("TestEditPassword") @@ -386,6 +394,7 @@ def test_account_required_field_password( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.environment.select("Value2") account.entity.multiple_select.select("Option Two") account.entity.username.set_value("TestEditUser") @@ -418,6 +427,7 @@ def test_account_required_field_name( """Verifies required field name""" account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.environment.select("Value2") account.entity.multiple_select.select("Option Two") account.entity.username.set_value("TestEditUser") @@ -430,6 +440,66 @@ def test_account_required_field_name( left_args={"expect_error": True}, ) + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_example_file( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field example_file""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.environment.select("Value2") + account.entity.multiple_select.select("Option Two") + account.entity.username.set_value("TestEditUser") + account.entity.password.set_value("TestEditPassword") + account.entity.security_token.set_value("TestEditToken") + account.entity.account_radio.select("No") + self.assert_util( + account.entity.save, + "Field Example File is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.account + @pytest.mark.forwarder + def test_account_example_file_validations( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the file input validations""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.name.set_value(ACCOUNT_CONFIG.get("name")) + # test for invalid file format + account.entity.file.set_value(os.path.abspath(INVALID_FILE)) + self.assert_util( + account.entity.file.get_error_text, + "The file must be in one of these formats: conf, txt", + ) + self.assert_util(account.entity.file.cancel_selected_value, True) + # test for file size limit + account.entity.file.set_value(os.path.abspath(LARGE_SIZE_FILE)) + self.assert_util( + account.entity.file.get_error_text, "The file size should not exceed 1 KB" + ) + self.assert_util(account.entity.file.cancel_selected_value, True) + # test for invalid file content + account.entity.file.set_value(os.path.abspath(INVALID_FILE_CONTENT)) + self.assert_util(account.entity.file.get_value, "invalid_file_content.conf") + account.entity.environment.select("Value2") + account.entity.multiple_select.select("Option Two") + account.entity.username.set_value("TestEditUser") + account.entity.password.set_value("TestEditPassword") + account.entity.security_token.set_value("TestEditToken") + account.entity.account_radio.select("No") + self.assert_util( + account.entity.save, + "Field Example File does not match regular expression ^Example*", + left_args={"expect_error": True}, + ) + @pytest.mark.execute_enterprise_cloud_true @pytest.mark.forwarder @pytest.mark.account @@ -440,6 +510,7 @@ def test_account_basic_fields_label_entity( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() self.assert_util(account.entity.name.get_input_label, "Name") + self.assert_util(account.entity.file.get_input_label, "Example File") self.assert_util( account.entity.environment.get_input_label, "Example Environment" ) @@ -494,6 +565,10 @@ def test_account_help_text_entity( self.assert_util( account.entity.name.get_help_text, "Enter a unique name for this account." ) + self.assert_util(account.entity.file.get_help_text, "Upload example file") + self.assert_util( + account.entity.file.get_support_message, "Example Support message" + ) self.assert_util( account.entity.example_checkbox.get_help_text, "This is an example checkbox for the account entity", @@ -532,6 +607,7 @@ def test_account_required_field_example_environment( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.multiple_select.select("Option Two") account.entity.username.set_value("TestEditUser") account.entity.password.set_value("TestEditPassword") @@ -554,6 +630,7 @@ def test_account_required_field_example_multiple_select( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.environment.select("Value2") account.entity.username.set_value("TestEditUser") account.entity.password.set_value("TestEditPassword") @@ -575,6 +652,7 @@ def test_account_required_field_client_id( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.environment.select("Value2") account.entity.account_radio.select("No") account.entity.multiple_select.select("Option Two") @@ -596,6 +674,7 @@ def test_account_required_field_client_secret( account.entity.open() account.entity.auth_key.select("OAuth 2.0 Authentication") account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.multiple_select.select("Option One") account.entity.account_radio.select("No") account.entity.client_id.set_value("TestClientId") @@ -627,6 +706,7 @@ def test_account_valid_account_name( """Verifies whether adding special characters, number in starting of name field displays validation error""" account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.username.set_value(ACCOUNT_CONFIG["username"]) account.entity.password.set_value(ACCOUNT_CONFIG["password"]) account.entity.name.set_value("123TestAccount") @@ -645,6 +725,7 @@ def test_account_valid_length_name( """Verifies the name field should not be more than 50 characters""" account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.username.set_value(ACCOUNT_CONFIG["username"]) account.entity.password.set_value(ACCOUNT_CONFIG["password"]) account.entity.name.set_value("t" * 51) @@ -796,6 +877,7 @@ def test_add_account_duplicate_name( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.multiple_select.select("Option One") account.entity.username.set_value(ACCOUNT_CONFIG["username"]) account.entity.password.set_value(ACCOUNT_CONFIG["password"]) @@ -849,6 +931,7 @@ def test_account_credentials_encrypted_value( "disabled": False, "password": "******", "token": "******", + "example_file": "******", } @pytest.mark.execute_enterprise_cloud_true @@ -862,6 +945,7 @@ def test_account_add_frontend_validation( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.username.set_value(ACCOUNT_CONFIG["username"]) account.entity.multiple_select.select("Option One") account.entity.password.set_value(ACCOUNT_CONFIG["password"]) @@ -887,6 +971,7 @@ def test_account_edit_frontend_validation( """Verifies the frontend edit functionality""" account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.table.edit_row(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.environment.select("Value2") account.entity.multiple_select.select("Option Two") account.entity.username.set_value("TestEditUser") @@ -932,6 +1017,7 @@ def test_account_clone_frontend_validation( account.table.wait_for_rows_to_appear(1) account.table.clone_row(ACCOUNT_CONFIG["name"]) account.entity.name.set_value("TestAccount2") + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.username.set_value("TestUserClone") account.entity.password.set_value("TestPasswordClone") account.entity.security_token.set_value("TestTokenClone") @@ -956,6 +1042,7 @@ def test_account_clone_default_values( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.table.clone_row(ACCOUNT_CONFIG["name"]) self.assert_util(account.entity.name.get_value, "") + self.assert_util(account.entity.file.get_value, "Previous File") self.assert_util(account.entity.username.get_value, "TestUser") self.assert_util(account.entity.multiple_select.get_values, ["Option One"]) self.assert_util(account.entity.auth_key.get_value, "basic") @@ -971,6 +1058,7 @@ def test_account_add_backend_validation( account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.entity.open() account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.username.set_value(ACCOUNT_CONFIG["username"]) account.entity.multiple_select.select("Option One") account.entity.password.set_value(ACCOUNT_CONFIG["password"]) @@ -988,6 +1076,7 @@ def test_account_add_backend_validation( "disabled": False, "password": ACCOUNT_CONFIG["password"], "token": ACCOUNT_CONFIG["token"], + "example_file": "Example test file for testing file component", } @pytest.mark.execute_enterprise_cloud_true @@ -1000,6 +1089,7 @@ def test_account_edit_backend_validation( """Verifies the account in backend after editing account from frontend""" account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) account.table.edit_row(ACCOUNT_CONFIG["name"]) + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.multiple_select.select("Option Two") account.entity.username.set_value("TestEditUser") account.entity.password.set_value("TestEditPassword") @@ -1019,6 +1109,7 @@ def test_account_edit_backend_validation( "disabled": False, "password": "TestEditPassword", "token": "TestEditToken", + "example_file": "Example test file for testing file component", } @pytest.mark.execute_enterprise_cloud_true @@ -1033,6 +1124,7 @@ def test_account_clone_backend_validation( account.table.wait_for_rows_to_appear(1) account.table.clone_row(ACCOUNT_CONFIG["name"]) account.entity.name.set_value("TestAccountClone") + account.entity.file.set_value(os.path.abspath(ACCOUNT_CONFIG["example_file"])) account.entity.multiple_select.select("Option Two") account.entity.username.set_value("TestCloneUser") account.entity.password.set_value("TestEditPassword") @@ -1050,6 +1142,7 @@ def test_account_clone_backend_validation( "disabled": False, "password": "TestEditPassword", "token": "TestEditToken", + "example_file": "Example test file for testing file component", } @pytest.mark.execute_enterprise_cloud_true diff --git a/tests/ui/test_splunk_ta_example_addon_input_1.py b/tests/ui/test_splunk_ta_example_addon_input_1.py index 40af92df..5de1788a 100644 --- a/tests/ui/test_splunk_ta_example_addon_input_1.py +++ b/tests/ui/test_splunk_ta_example_addon_input_1.py @@ -12,6 +12,7 @@ def add_account(ucc_smartx_rest_helper): url = account._get_account_endpoint() kwargs = { "name": "test_input", + "example_file": "Example file content", "account_checkbox": 1, "account_multiple_select": "one", "account_radio": "yes", diff --git a/tests/ui/test_splunk_ta_example_addon_input_2.py b/tests/ui/test_splunk_ta_example_addon_input_2.py index df134229..272e6cc6 100644 --- a/tests/ui/test_splunk_ta_example_addon_input_2.py +++ b/tests/ui/test_splunk_ta_example_addon_input_2.py @@ -14,6 +14,7 @@ def add_account(ucc_smartx_rest_helper): url = account._get_account_endpoint() kwargs = { "name": "test_input", + "example_file": "Example file content", "account_checkbox": 1, "account_multiple_select": "one", "account_radio": "yes", diff --git a/tests/ui/test_splunk_ta_example_addon_input_common.py b/tests/ui/test_splunk_ta_example_addon_input_common.py index 85df5248..a661c551 100644 --- a/tests/ui/test_splunk_ta_example_addon_input_common.py +++ b/tests/ui/test_splunk_ta_example_addon_input_common.py @@ -12,6 +12,7 @@ def add_account(ucc_smartx_rest_helper): url = account._get_account_endpoint() kwargs = { "name": "test_input", + "example_file": "Example file content", "account_checkbox": 1, "account_multiple_select": "one", "account_radio": "yes", diff --git a/tests/ui/testdata/example_file.txt b/tests/ui/testdata/example_file.txt new file mode 100644 index 00000000..4ac9dfea --- /dev/null +++ b/tests/ui/testdata/example_file.txt @@ -0,0 +1 @@ +Example test file for testing file component \ No newline at end of file diff --git a/tests/ui/testdata/invalid_file.json b/tests/ui/testdata/invalid_file.json new file mode 100644 index 00000000..cf6ce97b --- /dev/null +++ b/tests/ui/testdata/invalid_file.json @@ -0,0 +1,3 @@ +{ + "test": "Dummy Data" +} diff --git a/tests/ui/testdata/invalid_file_content.conf b/tests/ui/testdata/invalid_file_content.conf new file mode 100644 index 00000000..1867e8b5 --- /dev/null +++ b/tests/ui/testdata/invalid_file_content.conf @@ -0,0 +1 @@ +Invalid content \ No newline at end of file diff --git a/tests/ui/testdata/large_file.txt b/tests/ui/testdata/large_file.txt new file mode 100644 index 00000000..f208e967 --- /dev/null +++ b/tests/ui/testdata/large_file.txt @@ -0,0 +1,20 @@ +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. +Example file with large size to test the file input size validation in UCC. \ No newline at end of file