From ac61ebb7bad3ea614d81abc76feca177566c6b91 Mon Sep 17 00:00:00 2001 From: Artem Rys Date: Mon, 11 Sep 2023 21:53:31 +0200 Subject: [PATCH 1/5] chore: separating from ucc-example repository --- .github/workflows/build-test-release.yaml | 67 +- .gitignore | 2 - .gitmodules | 4 - Dockerfile-saucelabs | 10 +- Dockerfile-tests | 15 +- poetry.lock | 290 +- pyproject.toml | 13 +- tests/deps/splunk-add-on-for-ucc-example | 1 - tests/entrypoint.sh | 8 +- tests/pytest-ci.ini | 23 - .../Splunk_TA_UCCExample/globalConfig.json | 1051 ++++++++ .../Splunk_TA_UCCExample/package/README.txt | 6 + .../Splunk_TA_UCCExample/package/app.manifest | 52 + .../package/appserver/static/test_alert.png | Bin 0 -> 3348 bytes .../package/default/alert_actions.conf | 19 + .../package/default/app.conf | 31 + .../package/lib/requirements.txt | 12 + .../package/static/appIcon.png | Bin 0 -> 3348 bytes .../package/static/appIconAlt.png | Bin 0 -> 3348 bytes .../package/static/appIconAlt_2x.png | Bin 0 -> 6738 bytes .../package/static/appIcon_2x.png | Bin 0 -> 6738 bytes tests/ui/.pytest.expect | 7 + tests/ui/Example_UccLib/__init__.py | 0 tests/ui/Example_UccLib/account.py | 163 ++ tests/ui/Example_UccLib/alert_action.py | 79 + tests/ui/Example_UccLib/custom.py | 99 + tests/ui/Example_UccLib/input_page.py | 255 ++ tests/ui/__init__.py | 0 tests/ui/pytest-ci.ini | 25 + .../test_splunk_ta_example_addon_account.py | 1102 ++++++++ ...t_splunk_ta_example_addon_alert_actions.py | 203 ++ .../ui/test_splunk_ta_example_addon_custom.py | 402 +++ .../ui/test_splunk_ta_example_addon_input.py | 2348 +++++++++++++++++ .../test_splunk_ta_example_addon_logging.py | 34 + .../ui/test_splunk_ta_example_addon_proxy.py | 374 +++ tests/unit/pytest.ini | 1 - 36 files changed, 6584 insertions(+), 112 deletions(-) delete mode 160000 tests/deps/splunk-add-on-for-ucc-example delete mode 100644 tests/pytest-ci.ini create mode 100644 tests/testdata/Splunk_TA_UCCExample/globalConfig.json create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/README.txt create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/app.manifest create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/appserver/static/test_alert.png create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/default/alert_actions.conf create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/default/app.conf create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/lib/requirements.txt create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/static/appIcon.png create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/static/appIconAlt.png create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/static/appIconAlt_2x.png create mode 100644 tests/testdata/Splunk_TA_UCCExample/package/static/appIcon_2x.png create mode 100644 tests/ui/.pytest.expect create mode 100644 tests/ui/Example_UccLib/__init__.py create mode 100644 tests/ui/Example_UccLib/account.py create mode 100644 tests/ui/Example_UccLib/alert_action.py create mode 100644 tests/ui/Example_UccLib/custom.py create mode 100644 tests/ui/Example_UccLib/input_page.py create mode 100644 tests/ui/__init__.py create mode 100644 tests/ui/pytest-ci.ini create mode 100644 tests/ui/test_splunk_ta_example_addon_account.py create mode 100644 tests/ui/test_splunk_ta_example_addon_alert_actions.py create mode 100644 tests/ui/test_splunk_ta_example_addon_custom.py create mode 100644 tests/ui/test_splunk_ta_example_addon_input.py create mode 100644 tests/ui/test_splunk_ta_example_addon_logging.py create mode 100644 tests/ui/test_splunk_ta_example_addon_proxy.py diff --git a/.github/workflows/build-test-release.yaml b/.github/workflows/build-test-release.yaml index df84d254..dfc09efc 100644 --- a/.github/workflows/build-test-release.yaml +++ b/.github/workflows/build-test-release.yaml @@ -97,45 +97,20 @@ jobs: - uses: actions/setup-python@v4 with: python-version: 3.7 - - name: Install tools - run: | - curl -sSL https://install.python-poetry.org | python3 - --version 1.4.2 - - name: Build Package - run: | + - run: curl -sSL https://install.python-poetry.org | python3 - --version 1.4.2 + - run: | poetry install poetry build - - name: artifact-splunk-unpacked - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v3 with: name: package path: dist/* if: always() - prerequisites-ui-tests: - runs-on: ubuntu-latest - outputs: - ta_example_version: ${{ steps.ta-example.outputs.version }} - steps: - - name: Fetch latest version of Splunk_TA example - id: ta-example - run: | - ta_example_version=`basename $(curl -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' -s https://api.github.com/repos/splunk/splunk-add-on-for-ucc-example/releases/latest | jq -r '.assets | last | .browser_download_url')` - echo "version=$ta_example_version" >> $GITHUB_OUTPUT - - name: Cache Splunk_TA example - id: cache_ta - uses: actions/cache@v3 - with: - path: Splunk_TA*.spl - key: ${{ steps.ta-example.outputs.version }} - - name: Download Splunk_TA example - if: steps.cache_ta.outputs.cache-hit != 'true' - run: curl -s https://api.github.com/repos/splunk/splunk-add-on-for-ucc-example/releases/latest | jq -r '.assets | last | .browser_download_url' | wget -i - - run-ui-tests: needs: - meta - build - - prerequisites-ui-tests runs-on: ubuntu-latest permissions: id-token: write @@ -146,7 +121,7 @@ jobs: matrix: splunk: ${{ fromJson(needs.meta.outputs.matrix_supportedSplunk) }} browser: ["chrome", "firefox"] - test_suit: [ + test_suite: [ "test_splunk_ta_example_addon_logging", "test_splunk_ta_example_addon_account", "test_splunk_ta_example_addon_proxy", @@ -162,31 +137,31 @@ jobs: with: name: package path: dist/ - - name: update submodule - run: | - git submodule sync - git submodule update --recursive --remote - - name: Cache Splunk_TA example - id: cache_ta - uses: actions/cache@v3 + - run: | + git submodule sync + git submodule update --recursive --remote + - uses: actions/setup-python@v4 with: - path: Splunk_TA*.spl - key: ${{ needs.prerequisites-ui-tests.outputs.ta_example_version }} + python-version: 3.7 + - run: curl -sSL https://install.python-poetry.org | python3 - --version 1.4.2 - name: Setup for testing run: | - mkdir output test-results - tar -xvf Splunk_TA*.spl -C output/ - pip install git+https://github.com/pixelb/crudini + poetry install + poetry run ucc-gen build \ + --source=tests/testdata/Splunk_TA_UCCExample/package \ + --config=tests/testdata/Splunk_TA_UCCExample/globalConfig.json \ + --ta-version=0.0.1 - name: Splunk Testing run: | + mkdir test-results export SPLUNK_VERSION=${{ matrix.splunk.version }} - SPLUNK_APP_ID=$(crudini --get tests/deps/splunk-add-on-for-ucc-example/package/default/app.conf id name) + SPLUNK_APP_ID=Splunk_TA_UCCExample export SPLUNK_APP_ID - SPLUNK_APP_PACKAGE=output/$(ls output/) + SPLUNK_APP_PACKAGE=output/Splunk_TA_UCCExample export SPLUNK_APP_PACKAGE export TEST_SET=tests/ui export TEST_BROWSER="${{ matrix.browser }}" - export TEST_SUITE="-k ${{ matrix.test_suit }}" + export TEST_SUITE="-k ${{ matrix.test_suite }}" export SAUCE_USERNAME="${{ secrets.SAUCE_USERNAME }}" export SAUCE_PASSWORD="${{ secrets.SAUCE_PASSWORD }}" export SAUCE_TUNNEL_ID="${{ secrets.SAUCE_TUNNEL_ID }}" @@ -229,12 +204,12 @@ jobs: - uses: actions/upload-artifact@v3 if: always() with: - name: test-results-${{ matrix.splunk }}_${{ matrix.python-version }}_${{ matrix.browser }}_${{ matrix.test_suit }} + name: test-results-${{ matrix.splunk }}_${{ matrix.python-version }}_${{ matrix.browser }}_${{ matrix.test_suite }} path: test-results/* - uses: dorny/test-reporter@v1 if: always() with: - name: test-report-${{ matrix.splunk }}_${{ matrix.python-version }}_${{ matrix.browser }}_${{ matrix.test_suit }} + name: test-report-${{ matrix.splunk }}_${{ matrix.python-version }}_${{ matrix.browser }}_${{ matrix.test_suite }} path: "test-results/*.xml" reporter: java-junit diff --git a/.gitignore b/.gitignore index b6e47617..990ed2d2 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ @@ -30,7 +29,6 @@ MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest *.spec # Installer logs diff --git a/.gitmodules b/.gitmodules index bc4f4595..90280943 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ -[submodule "tests/deps/splunk-add-on-for-ucc-example"] - path = tests/deps/splunk-add-on-for-ucc-example - branch = main - url = https://github.com/splunk/splunk-add-on-for-ucc-example [submodule "tests/deps/build/addonfactory_test_matrix_splunk"] path = tests/deps/build/addonfactory_test_matrix_splunk url = https://github.com/splunk/addonfactory_test_matrix_splunk diff --git a/Dockerfile-saucelabs b/Dockerfile-saucelabs index 4d80aa3e..9129d8b5 100644 --- a/Dockerfile-saucelabs +++ b/Dockerfile-saucelabs @@ -13,15 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -#Splunk Connect for Syslog (SC4S) by Splunk, Inc. -# -#To the extent possible under law, the person who associated CC0 with -#Splunk Connect for Syslog (SC4S) has waived all copyright and related or neighboring rights -#to Splunk Connect for Syslog (SC4S). -# -#You should have received a copy of the CC0 legalcode along with this -#work. If not, see . FROM circleci/python:3.7 RUN curl https://saucelabs.com/downloads/sc-4.6.2-linux.tar.gz -o /home/circleci/saucelabs.tar.gz RUN tar -xzf /home/circleci/saucelabs.tar.gz --directory /home/circleci/ -CMD /home/circleci/sc-4.6.2-linux/bin/sc -u $SAUCE_USERNAME -k $SAUCE_PASSWORD -i $SAUCE_TUNNEL_ID --no-remove-colliding-tunnels -v --se-port 4445 \ No newline at end of file +CMD /home/circleci/sc-4.6.2-linux/bin/sc -u $SAUCE_USERNAME -k $SAUCE_PASSWORD -i $SAUCE_TUNNEL_ID --no-remove-colliding-tunnels -v --se-port 4445 diff --git a/Dockerfile-tests b/Dockerfile-tests index ab2ddfc3..8939f105 100644 --- a/Dockerfile-tests +++ b/Dockerfile-tests @@ -13,14 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # -#Splunk Connect for Syslog (SC4S) by Splunk, Inc. -# -#To the extent possible under law, the person who associated CC0 with -#Splunk Connect for Syslog (SC4S) has waived all copyright and related or neighboring rights -#to Splunk Connect for Syslog (SC4S). -# -#You should have received a copy of the CC0 legalcode along with this -#work. If not, see . FROM ubuntu:latest RUN mkdir -p /work/tests RUN mkdir -p /work/test-results/functional @@ -36,17 +28,16 @@ RUN export DEBIAN_FRONTEND=noninteractive ;\ ENV LANG en_US.utf8 COPY dist /work/dist -COPY tests/pytest-ci.ini /work/pytest.ini +COPY tests/ui/pytest-ci.ini /work/pytest.ini RUN pip install /work/dist/*.whl RUN pip install pytest-splunk-addon RUN pip install pytest-expect RUN pip install pytest-rerunfailures COPY tests/entrypoint.sh / -COPY tests/deps/splunk-add-on-for-ucc-example/tests /work/tests -COPY tests/deps/splunk-add-on-for-ucc-example/.pytest.expect /work/.pytest.expect +COPY tests /work/tests +COPY tests/ui/.pytest.expect /work/.pytest.expect RUN cd /work/tests && ls RUN cd ../.. -COPY tests/deps/splunk-add-on-for-ucc-example/package /work/package WORKDIR /work diff --git a/poetry.lock b/poetry.lock index 45a82751..f6bb8a8c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -24,6 +24,22 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] +[[package]] +name = "arrow" +version = "1.2.3" +description = "Better dates & times for Python" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, + {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + [[package]] name = "attrs" version = "23.1.0" @@ -61,6 +77,21 @@ files = [ [package.dependencies] pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} +[[package]] +name = "binaryornot" +version = "0.4.4" +description = "Ultra-lightweight pure Python package to check if a file is binary or text." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, + {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, +] + +[package.dependencies] +chardet = ">=3.0.2" + [[package]] name = "certifi" version = "2023.7.22" @@ -73,6 +104,18 @@ files = [ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] +[[package]] +name = "chardet" +version = "5.2.0" +description = "Universal encoding detector for Python 3" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, + {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, +] + [[package]] name = "charset-normalizer" version = "3.2.0" @@ -158,6 +201,22 @@ files = [ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + [[package]] name = "colorama" version = "0.4.6" @@ -170,6 +229,28 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cookiecutter" +version = "2.3.0" +description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cookiecutter-2.3.0-py3-none-any.whl", hash = "sha256:7e87944757c6e9f8729cf89a4139b6a35ab4d6dcbc6ae3e7d6360d44ad3ad383"}, + {file = "cookiecutter-2.3.0.tar.gz", hash = "sha256:942a794981747f6d7f439d6e49d39dc91a9a641283614160c93c474c72c29621"}, +] + +[package.dependencies] +arrow = "*" +binaryornot = ">=0.4.4" +click = ">=7.0,<9.0.0" +Jinja2 = ">=2.7,<4.0.0" +python-slugify = ">=4.0.0" +pyyaml = ">=5.3.1" +requests = ">=2.23.0" +rich = "*" + [[package]] name = "cssselect" version = "1.2.0" @@ -206,6 +287,22 @@ files = [ {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] +[[package]] +name = "dunamai" +version = "1.18.0" +description = "Dynamic version generation" +category = "dev" +optional = false +python-versions = ">=3.5,<4.0" +files = [ + {file = "dunamai-1.18.0-py3-none-any.whl", hash = "sha256:f9284a9f4048f0b809d11539896e78bde94c05b091b966a04a44ab4c48df03ce"}, + {file = "dunamai-1.18.0.tar.gz", hash = "sha256:5200598561ea5ba956a6174c36e402e92206c6a6aa4a93a6c5cb8003ee1e0997"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=1.6.0", markers = "python_version < \"3.8\""} +packaging = ">=20.9" + [[package]] name = "elementpath" version = "2.5.3" @@ -550,6 +647,32 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=0.29.35)"] +[[package]] +name = "markdown-it-py" +version = "2.2.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, + {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" +typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.3" @@ -620,6 +743,18 @@ files = [ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "msedge-selenium-tools" version = "3.141.4" @@ -635,6 +770,25 @@ files = [ [package.dependencies] selenium = "3.141" +[[package]] +name = "openapi3" +version = "1.8.2" +description = "Client and Validator of OpenAPI 3 Specifications" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "openapi3-1.8.2-py2.py3-none-any.whl", hash = "sha256:0d8fd34f304b61bc64b1f48ed6c6dbcc03ca04a29bcfa84e40ec5d87648e4399"}, + {file = "openapi3-1.8.2.tar.gz", hash = "sha256:a21a490573d89ca69ada7cbe585adb2fca4964257f6f3a1df531f12815455d2c"}, +] + +[package.dependencies] +PyYaml = "*" +requests = "*" + +[package.extras] +test = ["fastapi (==0.76.0)", "hypercorn (==0.14.3)", "pydantic (==1.10.2)", "pytest", "pytest-asyncio (==0.16)", "uvloop (==0.17.0)"] + [[package]] name = "packaging" version = "23.1" @@ -916,6 +1070,24 @@ files = [ [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-slugify" +version = "8.0.1" +description = "A Python slugify application that also handles Unicode" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"}, + {file = "python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + [[package]] name = "pytz" version = "2023.3.post1" @@ -928,6 +1100,66 @@ files = [ {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, ] +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + [[package]] name = "requests" version = "2.31.0" @@ -950,6 +1182,26 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rich" +version = "13.5.2" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"}, + {file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "selenium" version = "3.141.0" @@ -1194,6 +1446,30 @@ files = [ lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "splunk-add-on-ucc-framework" +version = "5.28.5" +description = "Splunk Add-on SDK formerly UCC is a build and code generation framework" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "splunk_add_on_ucc_framework-5.28.5-py3-none-any.whl", hash = "sha256:3172cd78d64643ff16705fd8c12f804256ff4e33992bb6c976216adeef041f6d"}, + {file = "splunk_add_on_ucc_framework-5.28.5.tar.gz", hash = "sha256:5a72ea0839203598853e81247e40a0bd7bcbeb9343d673453c810c6906670bb5"}, +] + +[package.dependencies] +addonfactory-splunk-conf-parser-lib = ">=0.3.3,<0.4.0" +cookiecutter = ">=2.1.1,<3.0.0" +defusedxml = ">=0.7.1,<0.8.0" +dunamai = ">=1.9.0,<2.0.0" +jinja2 = ">=2,<4" +jsonschema = ">=4.4.0,<5.0.0" +openapi3 = ">=1.7.0,<2.0.0" +PyYAML = ">=6.0,<7.0" +requests = ">=2.31.0,<3.0.0" +urllib3 = "<2" + [[package]] name = "splunk-sdk" version = "1.7.4" @@ -1222,6 +1498,18 @@ defusedxml = ">=0.7.1,<0.8.0" httplib2 = ">=0.22.0,<0.23.0" splunk-sdk = ">=1.6.20" +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -1331,4 +1619,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "46d36308631d7cb35a868d918eb7861fc3b94b11f36a2c7fb31fd1358ba56b15" +content-hash = "8e402ccc26b507eb4147af5ba6a22450a9a0e709d681ab3618ab74b35d7d4256" diff --git a/pyproject.toml b/pyproject.toml index 8337b293..d50b1d20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,8 +16,8 @@ [tool.poetry] name = "pytest-splunk-addon-ui-smartx" description = "Library to support testing Splunk Add-on UX" -authors = ["rfaircloth-splunk "] -license = "APACHE-2.0" +authors = ["Splunk "] +license = "Apache-2.0" classifiers = [ "Framework :: Pytest", "Intended Audience :: Developers", @@ -43,14 +43,15 @@ cssselect = "*" lxml = "^4.8.0" pytest-splunk-addon = "^5.0.0" -[tool.poetry.dev-dependencies] +[tool.poetry.plugins] +pytest11 = { "ucc-smartx" = "pytest_splunk_addon_ui_smartx.plugin" } + +[tool.poetry.group.dev.dependencies] pytest = ">=5.4, <7.3" Sphinx = "*" sphinx_rtd_theme = "*" sphinx-panels = "*" - -[tool.poetry.plugins] -pytest11 = { "ucc-smartx" = "pytest_splunk_addon_ui_smartx.plugin" } +splunk-add-on-ucc-framework = "^5.28.5" [build-system] requires = ["poetry_core>=1.0.0"] diff --git a/tests/deps/splunk-add-on-for-ucc-example b/tests/deps/splunk-add-on-for-ucc-example deleted file mode 160000 index 7ac74bc5..00000000 --- a/tests/deps/splunk-add-on-for-ucc-example +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7ac74bc53da253e0d2509d5954e62a6cae4f5cf4 diff --git a/tests/entrypoint.sh b/tests/entrypoint.sh index 0f8d883b..453fb758 100755 --- a/tests/entrypoint.sh +++ b/tests/entrypoint.sh @@ -1,10 +1,4 @@ #!/bin/sh -## -## SPDX-FileCopyrightText: 2020 Splunk, Inc. -## SPDX-License-Identifier: LicenseRef-Splunk-1-2020 -## -## - cd /work RERUN_COUNT=${RERUN_COUNT:-1} @@ -17,4 +11,4 @@ pytest $@ ${TEST_SET} ${TEST_SUITE} --browser=${TEST_BROWSER} --reruns=${RERUN_C # Exit with result test_exit_code=$? -exit "$test_exit_code" \ No newline at end of file +exit "$test_exit_code" diff --git a/tests/pytest-ci.ini b/tests/pytest-ci.ini deleted file mode 100644 index bb8facaa..00000000 --- a/tests/pytest-ci.ini +++ /dev/null @@ -1,23 +0,0 @@ -## -## SPDX-FileCopyrightText: 2020 Splunk, Inc. -## SPDX-License-Identifier: LicenseRef-Splunk-1-2020 -## -## -[pytest] -norecursedirs = .git .venv venv build deps tests/deps node_modules package -addopts = -v -s --tb=long - --splunk-type=external - --splunk-host=splunk - --junitxml=/work/test-results/test.xml - --browser=firefox - --html=/work/test-results/report.html -filterwarnings = - ignore::DeprecationWarning -markers = - input: Input Page UI test cases - account: Account page UI test cases - custom: Template page UI test cases - proxy: Proxy page UI test cases - logging: Logging page UI test cases - forwarder: Tests to be executed on Splunk Forwarder - sanity_test: Sanity Tests \ No newline at end of file diff --git a/tests/testdata/Splunk_TA_UCCExample/globalConfig.json b/tests/testdata/Splunk_TA_UCCExample/globalConfig.json new file mode 100644 index 00000000..c883f0c8 --- /dev/null +++ b/tests/testdata/Splunk_TA_UCCExample/globalConfig.json @@ -0,0 +1,1051 @@ +{ + "pages": { + "configuration": { + "tabs": [ + { + "name": "account", + "table": { + "actions": [ + "edit", + "delete", + "clone" + ], + "header": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Auth Type", + "field": "auth_type" + } + ] + }, + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "string", + "errorMsg": "Length of ID should be between 1 and 50", + "minLength": 1, + "maxLength": 50 + }, + { + "type": "regex", + "errorMsg": "Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + } + ], + "options": { + "placeholder": "Required" + }, + "field": "name", + "help": "Enter a unique name for this account.", + "required": true + }, + { + "type": "singleSelect", + "label": "Example Environment", + "options": { + "disableSearch": true, + "autoCompleteFields": [ + { + "value": "login.example.com", + "label": "Value1" + }, + { + "value": "test.example.com", + "label": "Value2" + }, + { + "value": "other", + "label": "Other" + } + ], + "display": true + }, + "help": "", + "field": "custom_endpoint", + "defaultValue": "login.example.com", + "required": true + }, + { + "type": "text", + "label": "Endpoint URL", + "help": "Enter the endpoint URL.", + "field": "endpoint", + "options": { + "display": false + } + }, + { + "type": "checkbox", + "label": "Example Checkbox", + "field": "account_checkbox", + "help": "This is an example checkbox for the account entity" + }, + { + "type": "radio", + "label": "Example Radio", + "field": "account_radio", + "defaultValue": "yes", + "help": "This is an example radio button for the account entity", + "required": true, + "options": { + "items": [ + { + "value": "yes", + "label": "Yes" + }, + { + "value": "no", + "label": "No" + } + ], + "display": true + } + }, + { + "type": "multipleSelect", + "label": "Example Multiple Select", + "field": "account_multiple_select", + "help": "This is an example multipleSelect for account entity", + "required": true, + "options": { + "items": [ + { + "value": "one", + "label": "Option One" + }, + { + "value": "two", + "label": "Option Two" + } + ] + } + }, + { + "type": "oauth", + "field": "oauth", + "label": "Not used", + "options": { + "auth_type": [ + "basic", + "oauth" + ], + "basic": [ + { + "oauth_field": "username", + "label": "Username", + "help": "Enter the username for this account.", + "field": "username" + }, + { + "oauth_field": "password", + "label": "Password", + "encrypted": true, + "help": "Enter the password for this account.", + "field": "password" + }, + { + "oauth_field": "security_token", + "label": "Security Token", + "encrypted": true, + "help": "Enter the security token.", + "field": "token" + } + ], + "oauth": [ + { + "oauth_field": "client_id", + "label": "Client Id", + "field": "client_id", + "help": "Enter the Client Id for this account." + }, + { + "oauth_field": "client_secret", + "label": "Client Secret", + "field": "client_secret", + "encrypted": true, + "help": "Enter the Client Secret key for this account." + }, + { + "oauth_field": "redirect_url", + "label": "Redirect url", + "field": "redirect_url", + "help": "Copy and paste this URL into your app." + } + ], + "auth_code_endpoint": "/services/oauth2/authorize", + "access_token_endpoint": "/services/oauth2/token", + "oauth_timeout": 30, + "oauth_state_enabled": false + } + }, + { + "field": "example_help_link", + "label": "", + "type": "helpLink", + "options": { + "text": "Help Link", + "link": "https://docs.splunk.com/Documentation" + } + } + ], + "title": "Account" + }, + { + "name": "proxy", + "entity": [ + { + "type": "checkbox", + "label": "Enable", + "field": "proxy_enabled" + }, + { + "type": "singleSelect", + "label": "Proxy Type", + "options": { + "disableSearch": true, + "autoCompleteFields": [ + { + "value": "http", + "label": "http" + }, + { + "value": "socks4", + "label": "socks4" + }, + { + "value": "socks5", + "label": "socks5" + } + ] + }, + "defaultValue": "http", + "field": "proxy_type" + }, + { + "type": "text", + "label": "Host", + "validators": [ + { + "type": "regex", + "errorMsg": "Proxy Host should not have special characters", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Max host length is 4096", + "minLength": 0, + "maxLength": 4096 + } + ], + "field": "proxy_url" + }, + { + "type": "text", + "label": "Port", + "validators": [ + { + "type": "number", + "range": [ + 1, + 65535 + ] + } + ], + "field": "proxy_port" + }, + { + "type": "text", + "label": "Username", + "validators": [ + { + "type": "string", + "errorMsg": "Max length of username is 50", + "minLength": 0, + "maxLength": 50 + } + ], + "field": "proxy_username" + }, + { + "type": "text", + "label": "Password", + "validators": [ + { + "type": "string", + "errorMsg": "Max length of password is 8192", + "minLength": 0, + "maxLength": 8192 + } + ], + "encrypted": true, + "field": "proxy_password" + }, + { + "type": "checkbox", + "label": "Reverse DNS resolution", + "field": "proxy_rdns" + } + ], + "options": { + "saveValidator": "function(formData) { if(!formData.proxy_enabled || formData.proxy_enabled === '0') {return true; } if(!formData.proxy_url) { return 'Proxy Host can not be empty'; } if(!formData.proxy_port) { return 'Proxy Port can not be empty'; } if(!formData.proxy_type) {return 'Proxy type can not be empty'; } return true; }" + }, + "title": "Proxy" + }, + { + "name": "logging", + "entity": [ + { + "type": "singleSelect", + "label": "Log level", + "options": { + "disableSearch": true, + "autoCompleteFields": [ + { + "value": "DEBUG", + "label": "DEBUG" + }, + { + "value": "INFO", + "label": "INFO" + }, + { + "value": "WARNING", + "label": "WARNING" + }, + { + "value": "ERROR", + "label": "ERROR" + }, + { + "value": "CRITICAL", + "label": "CRITICAL" + } + ] + }, + "defaultValue": "INFO", + "field": "loglevel" + } + ], + "title": "Logging" + }, + { + "name": "custom_tab", + "title": "Customized Tab", + "entity": [ + { + "field": "test_string", + "label": "Test String", + "type": "text", + "validators": [ + { + "type": "string", + "maxLength": 10, + "minLength": 5 + } + ], + "required": true, + "options": { + "placeholder": "Required" + } + }, + { + "field": "test_number", + "label": "Test Number", + "type": "text", + "validators": [ + { + "type": "number", + "range": [ + 1, + 10 + ] + } + ], + "required": true, + "options": { + "placeholder": "Required" + } + }, + { + "field": "test_regex", + "label": "Test Regex", + "type": "text", + "validators": [ + { + "type": "regex", + "pattern": "^\\w+$", + "errorMsg": "Characters of Name should match regex ^\\w+$ ." + } + ] + }, + { + "field": "test_email", + "label": "Test Email", + "type": "text", + "validators": [ + { + "type": "email" + } + ] + }, + { + "field": "test_ipv4", + "label": "Test Ipv4", + "type": "text", + "validators": [ + { + "type": "ipv4" + } + ] + }, + { + "field": "test_date", + "label": "Test Date", + "type": "text", + "validators": [ + { + "type": "date" + } + ] + }, + { + "field": "test_url", + "label": "Test Url", + "type": "text", + "validators": [ + { + "type": "url" + } + ] + }, + { + "field": "test_radio", + "label": "Test Radio", + "type": "radio", + "defaultValue": "Yes", + "required": false, + "options": { + "items": [ + { + "value": "Yes", + "label": "Yes" + }, + { + "value": "No", + "label": "No" + } + ], + "display": true + } + }, + { + "field": "test_multiselect", + "label": "Test Multiselect", + "type": "multipleSelect", + "options": { + "delimiter": "|", + "items": [ + { + "value": "Option A", + "label": "Option A" + }, + { + "value": "Option B", + "label": "Option B" + } + ] + } + }, + { + "field": "test_help_link", + "label": "", + "type": "helpLink", + "options": { + "text": "Test Help Link", + "link": "https://docs.splunk.com/Documentation" + } + } + ] + } + ], + "title": "Configuration", + "description": "Set up your add-on" + }, + "inputs": { + "services": [ + { + "hook": { + "src": "Hook" + }, + "name": "example_input_one", + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "regex", + "errorMsg": "Input Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Length of input name should be between 1 and 100", + "minLength": 1, + "maxLength": 100 + } + ], + "field": "name", + "help": "A unique name for the data input.", + "required": true + }, + { + "type": "checkbox", + "label": "Example Checkbox", + "field": "input_one_checkbox", + "help": "This is an example checkbox for the input one entity", + "defaultValue": true + }, + { + "type": "radio", + "label": "Example Radio", + "field": "input_one_radio", + "defaultValue": "yes", + "help": "This is an example radio button for the input one entity", + "required": false, + "options": { + "items": [ + { + "value": "yes", + "label": "Yes" + }, + { + "value": "no", + "label": "No" + } + ], + "display": true + } + }, + { + "field": "singleSelectTest", + "label": "Single Select Group Test", + "type": "singleSelect", + "options": { + "createSearchChoice": true, + "autoCompleteFields": [ + { + "label": "Group1", + "children": [ + { + "value": "one", + "label": "One" + }, + { + "value": "two", + "label": "Two" + } + ] + }, + { + "label": "Group2", + "children": [ + { + "value": "three", + "label": "Three" + }, + { + "value": "four", + "label": "Four" + } + ] + } + ] + } + }, + { + "field": "multipleSelectTest", + "label": "Multiple Select Test", + "type": "multipleSelect", + "defaultValue": "a|b", + "options": { + "delimiter": "|", + "items": [ + { + "value": "a", + "label": "A" + }, + { + "value": "b", + "label": "B" + } + ] + } + }, + { + "type": "text", + "label": "Interval", + "validators": [ + { + "type": "regex", + "errorMsg": "Interval must be an integer.", + "pattern": "^\\-[1-9]\\d*$|^\\d*$" + } + ], + "field": "interval", + "help": "Time interval of the data input, in seconds.", + "required": true + }, + { + "type": "singleSelect", + "label": "Index", + "validators": [ + { + "type": "string", + "errorMsg": "Length of index name should be between 1 and 80.", + "minLength": 1, + "maxLength": 80 + } + ], + "defaultValue": "default", + "options": { + "endpointUrl": "data/indexes", + "createSearchChoice": true, + "denyList": "^_.*$" + }, + "field": "index", + "required": true + }, + { + "type": "singleSelect", + "label": "Example Account", + "options": { + "referenceName": "account" + }, + "help": "", + "field": "account", + "required": true + }, + { + "type": "text", + "label": "Object", + "validators": [ + { + "type": "string", + "errorMsg": "Max length of text input is 8192", + "minLength": 0, + "maxLength": 8192 + } + ], + "field": "object", + "help": "The name of the object to query for.", + "required": true + }, + { + "type": "text", + "label": "Object Fields", + "validators": [ + { + "type": "string", + "errorMsg": "Max length of text input is 8192", + "minLength": 0, + "maxLength": 8192 + } + ], + "field": "object_fields", + "help": "Object fields from which to collect data. Delimit multiple fields using a comma.", + "required": true + }, + { + "type": "text", + "label": "Order By", + "validators": [ + { + "type": "string", + "errorMsg": "Max length of text input is 8192", + "minLength": 0, + "maxLength": 8192 + } + ], + "defaultValue": "LastModifiedDate", + "field": "order_by", + "help": "The datetime field by which to query results in ascending order for indexing.", + "required": true + }, + { + "type": "text", + "label": "Query Start Date", + "validators": [ + { + "type": "regex", + "errorMsg": "Invalid date and time format", + "pattern": "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}z)?$" + } + ], + "field": "start_date", + "help": "The datetime after which to query and index records, in this format: \"YYYY-MM-DDThh:mm:ss.000z\".\nDefaults to 90 days earlier from now.", + "tooltip": "Changing this parameter may result in gaps or duplication in data collection.", + "required": false + }, + { + "type": "text", + "label": "Limit", + "validators": [ + { + "type": "string", + "errorMsg": "Max length of text input is 8192", + "minLength": 0, + "maxLength": 8192 + } + ], + "defaultValue": "1000", + "field": "limit", + "help": "The maximum number of results returned by the query.", + "required": false + }, + { + "field": "example_help_link", + "label": "", + "type": "helpLink", + "options": { + "text": "Help Link", + "link": "https://docs.splunk.com/Documentation" + } + } + ], + "title": "Example Input One" + }, + { + "name": "example_input_two", + "entity": [ + { + "type": "text", + "label": "Name", + "validators": [ + { + "type": "regex", + "errorMsg": "Input Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + "pattern": "^[a-zA-Z]\\w*$" + }, + { + "type": "string", + "errorMsg": "Length of input name should be between 1 and 100", + "minLength": 1, + "maxLength": 100 + } + ], + "field": "name", + "help": "A unique name for the data input.", + "required": true + }, + { + "type": "text", + "label": "Interval", + "validators": [ + { + "type": "regex", + "errorMsg": "Interval must be an integer.", + "pattern": "^\\-[1-9]\\d*$|^\\d*$" + } + ], + "field": "interval", + "help": "Time interval of the data input, in seconds .", + "required": true + }, + { + "type": "singleSelect", + "label": "Index", + "validators": [ + { + "type": "string", + "errorMsg": "Length of index name should be between 1 and 80.", + "minLength": 1, + "maxLength": 80 + } + ], + "defaultValue": "default", + "options": { + "endpointUrl": "data/indexes", + "createSearchChoice": true, + "denyList": "^_.*$" + }, + "field": "index", + "required": true + }, + { + "type": "singleSelect", + "label": "Example Account", + "options": { + "referenceName": "account" + }, + "help": "", + "field": "account", + "required": true + }, + { + "type": "multipleSelect", + "label": "Example Multiple Select", + "field": "input_two_multiple_select", + "help": "This is an example multipleSelect for input two entity", + "required": true, + "options": { + "items": [ + { + "value": "one", + "label": "Option One" + }, + { + "value": "two", + "label": "Option Two" + } + ] + } + }, + { + "type": "checkbox", + "label": "Example Checkbox", + "field": "input_two_checkbox", + "help": "This is an example checkbox for the input two entity" + }, + { + "type": "radio", + "label": "Example Radio", + "field": "input_two_radio", + "help": "This is an example radio button for the input two entity", + "required": true, + "options": { + "items": [ + { + "value": "yes", + "label": "Yes" + }, + { + "value": "no", + "label": "No" + } + ], + "display": true + } + }, + { + "type": "text", + "label": "Query Start Date", + "validators": [ + { + "type": "regex", + "errorMsg": "Invalid date and time format", + "pattern": "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}z)?$" + } + ], + "field": "start_date", + "help": "The date and time, in \"YYYY-MM-DDThh:mm:ss.000z\" format, after which to query and index records. \nThe default is 90 days before today.", + "tooltip": "Changing this parameter may result in gaps or duplication in data collection.", + "required": false + }, + { + "field": "example_help_link", + "label": "", + "type": "helpLink", + "options": { + "text": "Help Link", + "link": "https://docs.splunk.com/Documentation" + } + } + ], + "title": "Example Input Two" + } + ], + "title": "Inputs", + "description": "Manage your data inputs", + "table": { + "actions": [ + "edit", + "enable", + "delete", + "clone" + ], + "header": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Account", + "field": "account" + }, + { + "label": "Interval", + "field": "interval" + }, + { + "label": "Index", + "field": "index" + }, + { + "label": "Status", + "field": "disabled" + } + ], + "moreInfo": [ + { + "label": "Name", + "field": "name" + }, + { + "label": "Interval", + "field": "interval" + }, + { + "label": "Index", + "field": "index" + }, + { + "label": "Status", + "field": "disabled", + "mapping": { + "true": "Disabled", + "false": "Enabled" + } + }, + { + "label": "Example Account", + "field": "account" + }, + { + "label": "Object", + "field": "object" + }, + { + "label": "Object Fields", + "field": "object_fields" + }, + { + "label": "Order By", + "field": "order_by" + }, + { + "label": "Query Start Date", + "field": "start_date" + }, + { + "label": "Limit", + "field": "limit" + } + ] + } + } + }, + "alerts": [ + { + "name": "test_alert", + "label": "Test Alert", + "description": "Description for test Alert Action", + "activeResponse": { + "task": [ + "Create", + "Update" + ], + "supportsAdhoc": true, + "subject": [ + "endpoint" + ], + "category": [ + "Information Conveyance", + "Information Portrayal" + ], + "technology": [ + { + "version": [ + "1.0.0" + ], + "product": "Test Incident Update", + "vendor": "Splunk" + } + ], + "drilldownUri": "search?q=search%20index%3D\"_internal\"&earliest=0&latest=", + "sourcetype": "test:incident" + }, + "entity": [ + { + "type": "text", + "label": "Name", + "field": "name", + "defaultValue": "xyz", + "required": true, + "help": "Please enter your name" + }, + { + "type": "checkbox", + "label": "All Incidents", + "field": "all_incidents", + "defaultValue": 0, + "required": false, + "help": "Tick if you want to update all incidents/problems" + }, + { + "type": "singleSelect", + "label": "Table List", + "field": "table_list", + "options": { + "items": [ + { + "value": "Incident", + "label": "incident" + }, + { + "value": "Problem", + "label": "problem" + } + ] + }, + "help": "Please select the table", + "required": false, + "defaultValue": "problem" + }, + { + "type": "radio", + "label": "Action:", + "field": "action", + "options": { + "items": [ + { + "value": "Update", + "label": "update" + }, + { + "value": "Delete", + "label": "delete" + } + ] + }, + "help": "Select the action you want to perform", + "required": true, + "defaultValue": "two" + }, + { + "type": "singleSelectSplunkSearch", + "label": "Select Account", + "field": "account", + "search": "| rest /servicesNS/nobody/Splunk_TA_UCCExample/splunk_ta_uccexample_account | dedup title", + "valueField": "title", + "labelField": "title", + "help": "Select the account from the dropdown", + "required": true + } + ] + } + ], + "meta": { + "name": "Splunk_TA_UCCExample", + "restRoot": "splunk_ta_uccexample", + "version": "0.0.1", + "displayName": "Splunk UCC test Add-on", + "schemaVersion": "0.0.3" + } +} diff --git a/tests/testdata/Splunk_TA_UCCExample/package/README.txt b/tests/testdata/Splunk_TA_UCCExample/package/README.txt new file mode 100644 index 00000000..e037e02d --- /dev/null +++ b/tests/testdata/Splunk_TA_UCCExample/package/README.txt @@ -0,0 +1,6 @@ +Copyright (C) 2020 Splunk Inc. All Rights Reserved. + +# Binary File Declaration + +File: lib/charset_normalizer/md__mypyc.cpython-37m-x86_64-linux-gnu.so +File: lib/charset_normalizer/md.cpython-37m-x86_64-linux-gnu.so diff --git a/tests/testdata/Splunk_TA_UCCExample/package/app.manifest b/tests/testdata/Splunk_TA_UCCExample/package/app.manifest new file mode 100644 index 00000000..982f432d --- /dev/null +++ b/tests/testdata/Splunk_TA_UCCExample/package/app.manifest @@ -0,0 +1,52 @@ +{ + "schemaVersion": "2.0.0", + "info": { + "title": "Splunk_TA_UCCExample", + "id": { + "group": null, + "name": "Splunk_TA_UCCExample", + "version": "0.0.1" + }, + "author": [ + { + "name": "Splunk, Inc.", + "email": "support@splunk.com", + "company": "Splunk, Inc." + } + ], + "releaseDate": null, + "description": "Splunk_TA_UCCExample", + "classification": { + "intendedAudience": "IT Professionals", + "categories": [ + "Security, Fraud & Compliance" + ], + "developmentStatus": "Production/Stable" + }, + "commonInformationModels": null, + "license": { + "name": null, + "text": "LICENSES/LicenseRef-Splunk-8-2021.txt", + "uri": null + }, + "privacyPolicy": { + "name": null, + "text": null, + "uri": null + }, + "releaseNotes": { + "name": "README", + "text": "README.txt", + "uri": "https://docs.splunk.com/Documentation/AddOns/McAfeeEPOSyslog/About" + } + }, + "supportedDeployments": [ + "_standalone", + "_distributed", + "_search_head_clustering" + ], + "targetWorkloads": [ + "_search_heads", + "_indexers" + ] +} diff --git a/tests/testdata/Splunk_TA_UCCExample/package/appserver/static/test_alert.png b/tests/testdata/Splunk_TA_UCCExample/package/appserver/static/test_alert.png new file mode 100644 index 0000000000000000000000000000000000000000..88f67e7257157937dd747b21af2c7af4d3432386 GIT binary patch literal 3348 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 +## SPDX-License-Identifier: LicenseRef-Splunk-8-2021 +## +## + +[test_alert] +label = Test Alert +description = Description for test Alert Action +param._cam = {"task": ["Create", "Update"], "subject": ["endpoint"], "category": ["Information Conveyance", "Information Portrayal"], "technology": [{"version": ["1.0.0"], "product": "Test Incident Update", "vendor": "Splunk"}], "supports_adhoc": true, "drilldown_uri": "search?q=search%20index%3D\"_internal\"&earliest=0&latest="} +python.version = python3 +icon_path = test_alert.png +is_custom = 1 +payload_format = json +param.name = xyz +param.all_incidents = +param.table_list = problem +param.action = two +param.account = diff --git a/tests/testdata/Splunk_TA_UCCExample/package/default/app.conf b/tests/testdata/Splunk_TA_UCCExample/package/default/app.conf new file mode 100644 index 00000000..37c5a836 --- /dev/null +++ b/tests/testdata/Splunk_TA_UCCExample/package/default/app.conf @@ -0,0 +1,31 @@ +## +## SPDX-FileCopyrightText: 2020 Splunk, Inc. +## SPDX-License-Identifier: LicenseRef-Splunk-8-2021 +## +## + +[install] +is_configured = false +state = enabled +build = 1 + +[launcher] +author = Splunk, Inc. +description = Splunk_TA_UCCExample +version = 0.1.0 + +[ui] +is_visible = true +label = Splunk_TA_UCCExample +docs_section_override = AddOns:released + +[package] +id = Splunk_TA_UCCExample + + +[id] +name = Splunk_TA_UCCExample +version = 0.1.0 + +[triggers] +reload.splunk_ta_uccexample_settings = simple diff --git a/tests/testdata/Splunk_TA_UCCExample/package/lib/requirements.txt b/tests/testdata/Splunk_TA_UCCExample/package/lib/requirements.txt new file mode 100644 index 00000000..65c27f79 --- /dev/null +++ b/tests/testdata/Splunk_TA_UCCExample/package/lib/requirements.txt @@ -0,0 +1,12 @@ +certifi==2022.12.7 ; python_version >= "3.7" and python_version < "4" +charset-normalizer==3.0.1 ; python_version >= "3.7" and python_version < "4" +defusedxml==0.7.1 ; python_version >= "3.7" and python_version < "4.0" +idna==3.4 ; python_version >= "3.7" and python_version < "4" +pysocks==1.7.1 ; python_version >= "3.7" and python_version < "4.0" +requests==2.28.2 ; python_version >= "3.7" and python_version < "4" +solnlib==4.9.1 ; python_version >= "3.7" and python_version < "4.0" +sortedcontainers==2.4.0 ; python_version >= "3.7" and python_version < "4.0" +splunk-sdk==1.7.3 ; python_version >= "3.7" and python_version < "4.0" +splunktalib==3.0.3 ; python_version >= "3.7" and python_version < "4.0" +splunktaucclib==6.0.7 ; python_version >= "3.7" and python_version < "4.0" +urllib3==1.26.14 ; python_version >= "3.7" and python_version < "4" diff --git a/tests/testdata/Splunk_TA_UCCExample/package/static/appIcon.png b/tests/testdata/Splunk_TA_UCCExample/package/static/appIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..88f67e7257157937dd747b21af2c7af4d3432386 GIT binary patch literal 3348 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 DQ5yUX literal 0 HcmV?d00001 diff --git a/tests/testdata/Splunk_TA_UCCExample/package/static/appIcon_2x.png b/tests/testdata/Splunk_TA_UCCExample/package/static/appIcon_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c638b3f159fc4047a35e86d577c49cb0234f6933 GIT binary patch literal 6738 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 DQ5yUX literal 0 HcmV?d00001 diff --git a/tests/ui/.pytest.expect b/tests/ui/.pytest.expect new file mode 100644 index 00000000..2347e147 --- /dev/null +++ b/tests/ui/.pytest.expect @@ -0,0 +1,7 @@ +pytest-expect file v1 +(3, 7, 7, 'final', 0) +u'tests/knowledge/test_addon.py::Test_App::test_tags[eventtype="UCC_NOT_GENERATED"::tag::notalert]': FAIL +u'tests/knowledge/test_addon.py::Test_App::test_eventtype[eventtype::UCC_NOT_GENERATED]': FAIL +u'tests/ui/test_splunk_ta_example_addon_account.py::TestAccount::test_account_basic_fields_label_entity': FAIL +u'tests/ui/test_splunk_ta_example_addon_account.py::TestAccount::test_account_oauth_fields_label_entity': FAIL +u'tests/ui/test_splunk_ta_example_addon_input.py::TestInput::test_inputs_delete_enabled_input': FAIL diff --git a/tests/ui/Example_UccLib/__init__.py b/tests/ui/Example_UccLib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/ui/Example_UccLib/account.py b/tests/ui/Example_UccLib/account.py new file mode 100644 index 00000000..a6a76051 --- /dev/null +++ b/tests/ui/Example_UccLib/account.py @@ -0,0 +1,163 @@ +from pytest_splunk_addon_ui_smartx.pages.page import Page +from pytest_splunk_addon_ui_smartx.components.base_component import Selector +from pytest_splunk_addon_ui_smartx.components.base_component import BaseComponent +from pytest_splunk_addon_ui_smartx.components.tabs import Tab +from pytest_splunk_addon_ui_smartx.components.entity import Entity +from pytest_splunk_addon_ui_smartx.components.controls.button import Button +from pytest_splunk_addon_ui_smartx.components.controls.single_select import SingleSelect +from pytest_splunk_addon_ui_smartx.components.controls.oauth_select import OAuthSelect +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.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 +from pytest_splunk_addon_ui_smartx.components.conf_table import ConfigurationTable +from pytest_splunk_addon_ui_smartx.backend_confs import ListBackendConf + + +class AccountEntity(Entity): + """ + Form to configure a new Server + """ + + def __init__(self, browser, container): + """ + :param browser: The selenium webdriver + :param container: The container in which the entity is located in + """ + add_btn = Button( + browser, + Selector( + select=container.select + ' button[data-test="button"][label="Add"]' + ), + ) + entity_container = Selector(select='[data-test="modal"]') + + super().__init__(browser, entity_container, add_btn=add_btn) + + # Controls + self.name = TextBox( + browser, Selector(select='[data-test="control-group"][data-name="name"]') + ) + self.environment = SingleSelect( + browser, + Selector(select='[data-test="control-group"][data-name="custom_endpoint"]'), + False, + ) + self.account_radio = Toggle( + browser, + Selector(select='[data-test="control-group"][data-name="account_radio"]'), + ) + self.example_checkbox = Checkbox( + browser, + Selector( + select='[data-test="control-group"][data-name="account_checkbox"]' + ), + ) + self.multiple_select = MultiSelect( + browser, + Selector( + select='[data-test="control-group"][data-name="account_multiple_select"]' + ), + ) + self.auth_key = OAuthSelect( + browser, + Selector(select='[data-test="control-group"][data-name="auth_type"]'), + ) + self.username = TextBox( + browser, + Selector(select='[data-test="control-group"][data-name="username"]'), + ) + self.password = TextBox( + browser, + Selector(select='[data-test="control-group"][data-name="password"]'), + ) + self.security_token = TextBox( + browser, Selector(select='[data-test="control-group"][data-name="token"]') + ) + self.client_id = TextBox( + browser, + Selector(select='[data-test="control-group"][data-name="client_id"]'), + ) + self.client_secret = TextBox( + browser, + Selector(select='[data-test="control-group"][data-name="client_secret"]'), + ) + self.redirect_url = TextBox( + browser, + Selector(select='[data-test="control-group"][data-name="redirect_url"]'), + ) + self.search_query = TextBox( + browser, Selector(select='[data-test="textbox"][role="textbox"]') + ) + self.help_link = LearnMore( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="example_help_link"]' + ), + ) + self.title = BaseComponent(browser, Selector(select='[data-test="title"]')) + + +class AccountPage(Page): + """ + Page: Server page + """ + + def __init__( + self, + ucc_smartx_selenium_helper=None, + ucc_smartx_rest_helper=None, + open_page=True, + ): + """ + :param ucc_smartx_selenium_helper: smartx configuration fixture + """ + super().__init__(ucc_smartx_selenium_helper, ucc_smartx_rest_helper, open_page) + account_container = Selector(select='div[id="accountTab"]') + + if ucc_smartx_selenium_helper: + self.title = Message( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="column"] .pageTitle'), + ) + self.description = Message( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="column"] .pageSubtitle'), + ) + self.table = ConfigurationTable( + ucc_smartx_selenium_helper.browser, account_container + ) + self.entity = AccountEntity( + ucc_smartx_selenium_helper.browser, account_container + ) + + if ucc_smartx_rest_helper: + self.backend_conf = ListBackendConf( + self._get_account_endpoint(), + ucc_smartx_rest_helper.username, + ucc_smartx_rest_helper.password, + ) + + def open(self): + """ + Open the required page. Page(super) class opens the page by default. + """ + + self.browser.get( + "{}/en-US/app/Splunk_TA_UCCExample/configuration".format( + self.splunk_web_url + ) + ) + tab = Tab(self.browser) + tab.open_tab("account") + + def _get_account_endpoint(self): + """ + Get rest endpoint for the configuration + """ + return "{}/servicesNS/nobody/Splunk_TA_UCCExample/splunk_ta_uccexample_account".format( + self.splunk_mgmt_url + ) diff --git a/tests/ui/Example_UccLib/alert_action.py b/tests/ui/Example_UccLib/alert_action.py new file mode 100644 index 00000000..8e060e5a --- /dev/null +++ b/tests/ui/Example_UccLib/alert_action.py @@ -0,0 +1,79 @@ +from pytest_splunk_addon_ui_smartx.components.base_component import Selector +from pytest_splunk_addon_ui_smartx.pages.page import Page +from pytest_splunk_addon_ui_smartx.backend_confs import ListBackendConf +from pytest_splunk_addon_ui_smartx.alert_actions import AlertEntity, ActionEntity +from pytest_splunk_addon_ui_smartx.alert_actions.components.textbox import AlertTextBox +from pytest_splunk_addon_ui_smartx.alert_actions.components.checkbox import ( + AlertCheckbox, +) +from pytest_splunk_addon_ui_smartx.alert_actions.components.single_select import ( + AlertSingleSelect, +) +from pytest_splunk_addon_ui_smartx.alert_actions.components.toggle import AlertToggle +from pytest_splunk_addon_ui_smartx.alert_actions.components.account_select import ( + AlertAccountSelect, +) +from pytest_splunk_addon_ui_smartx.alert_actions.components.table import AlertTable + + +class TestAction(ActionEntity): + """ + Form to configure a new Input + """ + + def __init__(self, browser): + """ + :param browser: The selenium webdriver + :param container: The container in which the entity is located in + """ + + super().__init__(browser) + + # Controls + self.name = AlertTextBox( + browser, Selector(select="#test_alert_name"), use_child_input=True + ) + self.all_incident = AlertCheckbox( + browser, Selector(select="#test_alert_all_incidents") + ) + self.table_list = AlertSingleSelect( + browser, Selector(select="#test_alert_table_list") + ) + self.action = AlertToggle( + browser, Selector(select='input[name="action.test_alert.param.action"]') + ) + self.account = AlertAccountSelect( + browser, Selector(select="#test_alert_account") + ) + + +class AlertPage(Page): + def __init__( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, open_page=True + ): + super().__init__(ucc_smartx_selenium_helper, ucc_smartx_rest_helper, open_page) + if ucc_smartx_selenium_helper: + self.alert_table = AlertTable(ucc_smartx_selenium_helper.browser) + self.alert_entity = AlertEntity( + ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ) + self.action_entity = TestAction(ucc_smartx_selenium_helper.browser) + if ucc_smartx_rest_helper: + self.backend_conf = ListBackendConf( + self._get_alert_endpoint(), + ucc_smartx_rest_helper.username, + ucc_smartx_rest_helper.password, + ) + + def open(self): + """ + Abstract Method. Open the page + """ + self.browser.get( + self.splunk_web_url + "/en-US/manager/Splunk_TA_UCCExample/saved/searches" + ) + + def _get_alert_endpoint(self): + return "{}/servicesNS/admin/Splunk_TA_UCCExample/saved/searches/".format( + self.splunk_mgmt_url + ) diff --git a/tests/ui/Example_UccLib/custom.py b/tests/ui/Example_UccLib/custom.py new file mode 100644 index 00000000..2d7e1701 --- /dev/null +++ b/tests/ui/Example_UccLib/custom.py @@ -0,0 +1,99 @@ +from pytest_splunk_addon_ui_smartx.components.base_component import Selector +from pytest_splunk_addon_ui_smartx.components.tabs import Tab +from pytest_splunk_addon_ui_smartx.components.entity import Entity +from pytest_splunk_addon_ui_smartx.components.controls.textbox import TextBox +from pytest_splunk_addon_ui_smartx.components.controls.toggle import Toggle +from pytest_splunk_addon_ui_smartx.components.controls.multi_select import MultiSelect +from pytest_splunk_addon_ui_smartx.components.controls.learn_more import LearnMore +from pytest_splunk_addon_ui_smartx.backend_confs import SingleBackendConf + + +class Custom(Entity): + def __init__( + self, + ucc_smartx_selenium_helper=None, + ucc_smartx_rest_helper=None, + open_page=True, + ): + """ + :param ucc_smartx_selenium_helper: fixture contains browser, urls and session key + """ + entity_container = Selector(select='div[id="custom_tabTab"]') + + # Components + if ucc_smartx_selenium_helper: + super().__init__(ucc_smartx_selenium_helper.browser, entity_container) + self.splunk_web_url = ucc_smartx_selenium_helper.splunk_web_url + self.open() + self.test_string = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_string"]'), + ) + self.test_number = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_number"]'), + ) + self.test_regex = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_regex"]'), + ) + self.test_email = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_email"]'), + ) + self.test_ipv4 = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_ipv4"]'), + ) + self.test_date = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_date"]'), + ) + self.test_url = TextBox( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_url"]'), + ) + self.test_radio = Toggle( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="control-group"][data-name="test_radio"]'), + ) + self.test_multiselect = MultiSelect( + ucc_smartx_selenium_helper.browser, + Selector( + select='[data-test="control-group"][data-name="test_multiselect"]' + ), + ) + self.test_help_link = LearnMore( + ucc_smartx_selenium_helper.browser, + Selector( + select='[data-test="control-group"][data-name="test_help_link"]' + ), + ) + + if ucc_smartx_rest_helper: + self.splunk_mgmt_url = ucc_smartx_rest_helper.splunk_mgmt_url + self.backend_conf = SingleBackendConf( + self._get_custom_url(), + ucc_smartx_rest_helper.username, + ucc_smartx_rest_helper.password, + ) + + def open(self): + """ + Open the required page. Page(super) class opens the page by default. + """ + self.browser.get( + "{}/en-US/app/Splunk_TA_UCCExample/configuration".format( + self.splunk_web_url + ) + ) + tab = Tab(self.browser) + tab.open_tab("custom_tab") + + def _get_custom_url(self): + """ + get rest endpoint for the configuration + """ + return "{}/servicesNS/nobody/Splunk_TA_UCCExample/configs/conf-splunk_ta_uccexample_settings/custom_tab".format( + self.splunk_mgmt_url + ) diff --git a/tests/ui/Example_UccLib/input_page.py b/tests/ui/Example_UccLib/input_page.py new file mode 100644 index 00000000..91e053b2 --- /dev/null +++ b/tests/ui/Example_UccLib/input_page.py @@ -0,0 +1,255 @@ +from pytest_splunk_addon_ui_smartx.pages.page import Page +from pytest_splunk_addon_ui_smartx.components.base_component import Selector +from pytest_splunk_addon_ui_smartx.components.base_component import BaseComponent +from pytest_splunk_addon_ui_smartx.components.dropdown import Dropdown +from pytest_splunk_addon_ui_smartx.components.entity import Entity +from pytest_splunk_addon_ui_smartx.components.controls.button import Button +from pytest_splunk_addon_ui_smartx.components.controls.checkbox import Checkbox +from pytest_splunk_addon_ui_smartx.components.controls.learn_more import LearnMore +from pytest_splunk_addon_ui_smartx.components.controls.textbox import TextBox +from pytest_splunk_addon_ui_smartx.components.controls.single_select import SingleSelect +from pytest_splunk_addon_ui_smartx.components.controls.multi_select import MultiSelect +from pytest_splunk_addon_ui_smartx.components.controls.message import Message +from pytest_splunk_addon_ui_smartx.components.input_table import InputTable +from pytest_splunk_addon_ui_smartx.backend_confs import ListBackendConf +from pytest_splunk_addon_ui_smartx.components.controls.toggle import Toggle + + +class ExampleInputOne(Entity): + """ + Form to configure a new Input + """ + + def __init__(self, browser, container): + """ + :param browser: The selenium webdriver + :param container: The container in which the entity is located in + """ + add_btn = Button( + browser, Selector(select=container.select + '[id="addInputBtn"]') + ) + entity_container = Selector(select='[data-test="modal"]') + + super().__init__(browser, entity_container, add_btn=add_btn) + + # Controls + self.name = TextBox( + browser, Selector(select=' [data-test="control-group"][data-name="name"]') + ) + self.example_checkbox = Checkbox( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="input_one_checkbox"]' + ), + ) + self.example_radio = Toggle( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="input_one_radio"]' + ), + ) + self.single_select_group_test = SingleSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="singleSelectTest"]' + ), + allow_new_values=True, + ) + self.multiple_select_test = MultiSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="multipleSelectTest"]' + ), + ) + self.interval = TextBox( + browser, + Selector(select=' [data-test="control-group"][data-name="interval"]'), + ) + self.index = SingleSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="index"]' + ), + allow_new_values=True, + ) + self.example_account = SingleSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="account"]' + ), + ) + self.object = TextBox( + browser, Selector(select=' [data-test="control-group"][data-name="object"]') + ) + self.object_fields = TextBox( + browser, + Selector(select=' [data-test="control-group"][data-name="object_fields"]'), + ) + self.order_by = TextBox( + browser, + Selector(select=' [data-test="control-group"][data-name="order_by"]'), + ) + self.query_start_date = TextBox( + browser, + Selector(select=' [data-test="control-group"][data-name="start_date"]'), + ) + self.limit = TextBox( + browser, Selector(select=' [data-test="control-group"][data-name="limit"]') + ) + self.help_link = LearnMore( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="example_help_link"]' + ), + ) + self.title = BaseComponent(browser, Selector(select=' [data-test="title"]')) + + +class ExampleInputTwo(Entity): + """ + Form to configure a new Input + """ + + def __init__(self, browser, container): + """ + :param browser: The selenium webdriver + :param container: The container in which the entity is located in + """ + add_btn = Button( + browser, Selector(select=container.select + ' [id="addInputBtn"]') + ) + entity_container = Selector(select=' [data-test="modal"]') + + super().__init__(browser, entity_container, add_btn=add_btn) + + # Controls + self.name = TextBox( + browser, Selector(select='[data-test="control-group"][data-name="name"]') + ) + self.interval = TextBox( + browser, + Selector(select=' [data-test="control-group"][data-name="interval"]'), + ) + self.index = SingleSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="index"]' + ), + allow_new_values=True, + ) + self.example_account = SingleSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="account"]' + ), + ) + self.example_multiple_select = MultiSelect( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="input_two_multiple_select"]' + ), + ) + self.example_checkbox = Checkbox( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="input_two_checkbox"]' + ), + ) + self.example_radio = Toggle( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="input_two_radio"]' + ), + ) + self.query_start_date = TextBox( + browser, + Selector(select=' [data-test="control-group"][data-name="start_date"]'), + ) + self.help_link = LearnMore( + browser, + Selector( + select=entity_container.select + + ' [data-test="control-group"][data-name="example_help_link"]' + ), + ) + self.title = BaseComponent(browser, Selector(select=' [data-test="title"]')) + + +class InputPage(Page): + """ + Page: Input page + """ + + def __init__( + self, + ucc_smartx_selenium_helper=None, + ucc_smartx_rest_helper=None, + open_page=True, + ): + """ + :param browser: The selenium webdriver + :param urls: Splunk web & management url. {"web": , "mgmt": } + :param session_key: session key to access the rest endpoints + """ + super().__init__(ucc_smartx_selenium_helper, ucc_smartx_rest_helper, open_page) + + input_container = Selector(select=' div[role="main"]') + if ucc_smartx_selenium_helper: + self.title = Message( + ucc_smartx_selenium_helper.browser, + Selector(select=' [data-test="column"] .pageTitle'), + ) + self.description = Message( + ucc_smartx_selenium_helper.browser, + Selector(select=' [data-test="column"] .pageSubtitle'), + ) + self.create_new_input = Dropdown( + ucc_smartx_selenium_helper.browser, + Selector(select='[id="addInputBtn"]'), + ) + self.table = InputTable( + ucc_smartx_selenium_helper.browser, + input_container, + mapping={"status": "disabled", "input_type": 3}, + ) + self.entity1 = ExampleInputOne( + ucc_smartx_selenium_helper.browser, input_container + ) + self.entity2 = ExampleInputTwo( + ucc_smartx_selenium_helper.browser, input_container + ) + self.pagination = Dropdown( + ucc_smartx_selenium_helper.browser, Selector(select=".dropdownPage") + ) + self.type_filter = Dropdown( + ucc_smartx_selenium_helper.browser, Selector(select=".dropdownInput") + ) + + if ucc_smartx_rest_helper: + self.backend_conf = ListBackendConf( + self._get_input_endpoint(), + ucc_smartx_rest_helper.username, + ucc_smartx_rest_helper.password, + ) + + def open(self): + self.browser.get( + "{}/en-US/app/Splunk_TA_UCCExample/inputs".format(self.splunk_web_url) + ) + + def _get_input_endpoint(self): + return "{}/servicesNS/nobody/Splunk_TA_UCCExample/configs/conf-inputs".format( + self.splunk_mgmt_url + ) diff --git a/tests/ui/__init__.py b/tests/ui/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/ui/pytest-ci.ini b/tests/ui/pytest-ci.ini new file mode 100644 index 00000000..127e1a19 --- /dev/null +++ b/tests/ui/pytest-ci.ini @@ -0,0 +1,25 @@ +[pytest] +markers = + proxy: Proxy page UI Test cases + logging: Logging page UI Test cases + input: Input page UI Test cases + account: Account page UI Test cases + alert_action: Alert Actions Test cases + template: Template page UI Test cases + custom: Custom page UI test cases + liveenvironment: Tests need live server to successfully execute + oauth_account: Oauth Account UI test cases + sanity_test: For sanity check of addons + search_head: Tests to be run on Splunk search head + forwarder: Tests to be run on Forwarder/Standalone + execute_enterprise_cloud_true: Tests to be executed on enterprise cloud + execute_enterprise_cloud_false: Tests not to be executed on enterprise cloud +norecursedirs = .git .venv venv build deps tests/deps node_modules package +addopts = -v -s --tb=long + --splunk-type=external + --splunk-host=splunk + --junitxml=/work/test-results/test.xml + --browser=firefox + --html=/work/test-results/report.html +filterwarnings = + ignore::DeprecationWarning diff --git a/tests/ui/test_splunk_ta_example_addon_account.py b/tests/ui/test_splunk_ta_example_addon_account.py new file mode 100644 index 00000000..050ff97c --- /dev/null +++ b/tests/ui/test_splunk_ta_example_addon_account.py @@ -0,0 +1,1102 @@ +from pytest_splunk_addon_ui_smartx.base_test import UccTester +from .Example_UccLib.account import AccountPage +from .Example_UccLib.input_page import InputPage + +import pytest +import copy + + +ACCOUNT_CONFIG = { + "name": "TestAccount", + "account_checkbox": 1, + "account_multiple_select": "one", + "account_radio": "yes", + "auth_type": "basic", + "custom_endpoint": "login.example.com", + "username": "TestUser", + "password": "TestPassword", + "token": "TestToken", + "client_id": "", + "client_secret": "", + "redirect_url": "", + "endpoint": "", + "example_help_link": "", +} + + +@pytest.fixture +def add_input(ucc_smartx_rest_helper): + input_page = InputPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = input_page._get_input_endpoint() + kwargs = { + "name": "example_input_one://dummy_input_one", + "account": "TestAccount", + "input_one_checkbox": "1", + "input_one_radio": "1", + "interval": "90", + "limit": "1000", + "multipleSelectTest": "a|b", + "object": "test_object", + "object_fields": "test_field", + "order_by": "LastModifiedDate", + "singleSelectTest": "two", + "start_date": "2020-12-11T20:00:32.000z", + "disabled": 0, + } + yield input_page.backend_conf.post_stanza(url, kwargs) + input_page.backend_conf.delete_all_stanzas("search=dummy_input_one") + + +@pytest.fixture +def add_account(ucc_smartx_rest_helper): + account = AccountPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = account._get_account_endpoint() + kwargs = ACCOUNT_CONFIG + yield account.backend_conf.post_stanza(url, kwargs) + + +@pytest.fixture +def add_multiple_account(ucc_smartx_rest_helper): + account = AccountPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = account._get_account_endpoint() + for i in range(12): + kwargs = copy.deepcopy(ACCOUNT_CONFIG) + kwargs["name"] = kwargs["name"] + str(i) + account.backend_conf.post_stanza(url, kwargs) + + +@pytest.fixture(autouse=True) +def delete_accounts(ucc_smartx_rest_helper): + yield + account = AccountPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + account.backend_conf.delete_all_stanzas() + + +class TestAccount(UccTester): + + ############################ + ### TEST CASES FOR TABLE ### + ############################ + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_default_rows_in_table( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the default number of rows in the table""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util(account.table.get_row_count, 0) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_sort_functionality( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_multiple_account + ): + """Verifies sorting functionality for name column""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.sort_column("Name") + sort_order = account.table.get_sort_order() + column_values = list(account.table.get_column_values("Name")) + column_values = list(str(item) for item in column_values) + sorted_values = sorted(column_values, key=str.lower) + self.assert_util(sort_order["header"].lower(), "name") + self.assert_util(column_values, sorted_values) + self.assert_util(sort_order["ascending"], True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_count( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_multiple_account + ): + """Verifies count on table""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + account.table.get_count_title, + "{} Items".format(len(account.backend_conf.get_all_stanzas())), + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_accounts_filter_functionality_negative( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the filter functionality (Negative)""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.set_filter("hello") + self.assert_util(account.table.get_row_count, 0) + self.assert_util( + account.table.get_count_title, + "{} Item".format(account.table.get_row_count()), + ) + account.table.clean_filter() + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_accounts_filter_functionality_positive( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the filter functionality (Positive)""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.set_filter("TestAccount") + self.assert_util(account.table.get_row_count, 1) + self.assert_util( + account.table.get_count_title, + "{} Item".format(account.table.get_row_count()), + ) + account.table.clean_filter() + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_pagination( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_multiple_account + ): + """Verifies pagination list""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + name_column_page1 = account.table.get_column_values("name") + account.table.switch_to_next() + name_column_page2 = account.table.get_column_values("name") + self.assert_util(name_column_page1, name_column_page2, "!=") + + ################################### + #### TEST CASES FOR ENTITY #### + ################################### + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_title_and_description( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the title and description of the page""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util(account.title.wait_to_display, "Configuration") + self.assert_util(account.description.wait_to_display, "Set up your add-on") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_add_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the title of the 'Add Entity'""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util( + account.entity.title.container.get_attribute("textContent").strip(), + "Add Account", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_edit_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the title of the 'Edit Entity'""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.edit_row(ACCOUNT_CONFIG["name"]) + self.assert_util( + account.entity.title.container.get_attribute("textContent").strip(), + "Update Account", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_clone_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the title of the 'Clone Entity'""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.clone_row(ACCOUNT_CONFIG["name"]) + self.assert_util( + account.entity.title.container.get_attribute("textContent").strip(), + "Clone Account", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_delete_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the title of the 'Delete Entity'""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.delete_row(ACCOUNT_CONFIG["name"], prompt_msg=True) + self.assert_util( + account.entity.title.container.get_attribute("textContent").strip(), + "Delete Confirmation", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_add_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies close functionality at time of add""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util(account.entity.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_add_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies cancel functionality at time of add""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util(account.entity.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_delete_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies close functionality at time of delete""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + account.table.delete_row, + True, + left_args={"name": ACCOUNT_CONFIG["name"], "close": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_delete_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies cancel functionality at time of delete""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + + self.assert_util( + account.table.delete_row, + True, + left_args={"name": ACCOUNT_CONFIG["name"], "cancel": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_edit_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies close functionality at time of edit""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.edit_row(ACCOUNT_CONFIG["name"]) + self.assert_util(account.entity.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_edit_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies cancel functionality at time of edit""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.edit_row(ACCOUNT_CONFIG["name"]) + self.assert_util(account.entity.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_clone_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies close functionality at time of clone""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.clone_row(ACCOUNT_CONFIG["name"]) + self.assert_util(account.entity.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_clone_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies cancel functionality at time of clone""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.clone_row(ACCOUNT_CONFIG["name"]) + self.assert_util(account.entity.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_delete_valid_prompt_message( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the prompt message of the 'Delete Entity'""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + prompt_message = account.table.delete_row( + ACCOUNT_CONFIG["name"], prompt_msg=True + ) + self.assert_util( + prompt_message, + 'Are you sure you want to delete "{}" ? Ensure that no input is configured with "{}" as this will stop data collection for that input.'.format( + ACCOUNT_CONFIG["name"], ACCOUNT_CONFIG["name"] + ), + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_username( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies 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.environment.select("Value2") + account.entity.multiple_select.select("Option Two") + 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 Username is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_password( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies 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.environment.select("Value2") + account.entity.multiple_select.select("Option Two") + account.entity.username.set_value("TestEditUser") + account.entity.security_token.set_value("TestEditToken") + account.entity.account_radio.select("No") + self.assert_util( + account.entity.save, + "Field Password is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_encrypted_field_password( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies if the password field is masked or not in the Textbox""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + textbox_type = account.entity.password.get_type() + self.assert_util(textbox_type, "password") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field name""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + 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 Name is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_basic_fields_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies basic account field label""" + 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.environment.get_input_label, "Example Environment" + ) + self.assert_util( + account.entity.example_checkbox.get_input_label, "Example Checkbox" + ) + self.assert_util(account.entity.account_radio.get_input_label, "Example Radio") + self.assert_util( + account.entity.multiple_select.get_input_label, "Example Multiple Select" + ) + self.assert_util(account.entity.auth_key.get_input_label, "Auth Type") + self.assert_util(account.entity.username.get_input_label, "Username") + self.assert_util(account.entity.password.get_input_label, "Password") + self.assert_util( + account.entity.security_token.get_input_label, "Security Token" + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_oauth_fields_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies oauth account field label""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.auth_key.select("OAuth 2.0 Authentication") + self.assert_util(account.entity.name.get_input_label, "Name") + self.assert_util( + account.entity.environment.get_input_label, "Example Environment" + ) + self.assert_util( + account.entity.example_checkbox.get_input_label, "Example Checkbox" + ) + self.assert_util(account.entity.account_radio.get_input_label, "Example Radio") + self.assert_util( + account.entity.multiple_select.get_input_label, "Example Multiple Select" + ) + self.assert_util(account.entity.auth_key.get_input_label, "Auth Type") + self.assert_util(account.entity.client_id.get_input_label, "Client Id") + self.assert_util(account.entity.client_secret.get_input_label, "Client Secret") + self.assert_util(account.entity.redirect_url.get_input_label, "Redirect url") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_fields_placeholder_value( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies account field placeholder value""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util(account.entity.name.get_placeholder_value, "Required") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.account + def test_account_help_text_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies help text for the field name""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util( + account.entity.name.get_help_text, "Enter a unique name for this account." + ) + self.assert_util( + account.entity.example_checkbox.get_help_text, + "This is an example checkbox for the account entity", + ) + self.assert_util( + account.entity.account_radio.get_help_text, + "This is an example radio button for the account entity", + ) + self.assert_util( + account.entity.multiple_select.get_help_text, + "This is an example multipleSelect for account entity", + ) + self.assert_util( + account.entity.username.get_help_text, + "Enter the username for this account.", + ) + self.assert_util( + account.entity.password.get_help_text, + "Enter the password for this account.", + ) + self.assert_util( + account.entity.security_token.get_help_text, "Enter the security token." + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_example_environment( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies 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.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") + account.entity.environment.cancel_selected_value() + self.assert_util( + account.entity.save, + "Field Example Environment is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies 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.environment.select("Value2") + 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 Multiple Select is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_client_id( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies 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.environment.select("Value2") + account.entity.account_radio.select("No") + account.entity.multiple_select.select("Option Two") + account.entity.auth_key.select("OAuth 2.0 Authentication") + self.assert_util( + account.entity.save, + "Field Client Id is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_required_field_client_secret( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field client secret""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.auth_key.select("OAuth 2.0 Authentication") + account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.multiple_select.select("Option One") + account.entity.account_radio.select("No") + account.entity.client_id.set_value("TestClientId") + self.assert_util( + account.entity.save, + "Field Client Secret is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_encrypted_field_client_secret( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies if the password field is masked or not in the Textbox""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.auth_key.select("OAuth 2.0 Authentication") + textbox_type = account.entity.client_secret.get_type() + self.assert_util(textbox_type, "password") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_valid_account_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """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.username.set_value(ACCOUNT_CONFIG["username"]) + account.entity.password.set_value(ACCOUNT_CONFIG["password"]) + account.entity.name.set_value("123TestAccount") + self.assert_util( + account.entity.save, + "Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_valid_length_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """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.username.set_value(ACCOUNT_CONFIG["username"]) + account.entity.password.set_value(ACCOUNT_CONFIG["password"]) + account.entity.name.set_value("t" * 51) + self.assert_util( + account.entity.save, + "Length of ID should be between 1 and 50", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_default_value_example_environment( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of 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.username.set_value(ACCOUNT_CONFIG["username"]) + self.assert_util(account.entity.environment.get_value, "Value1") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_list_example_environment( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example environment list dropdown""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util( + account.entity.environment.list_of_values, ["Value1", "Value2", "Other"] + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_default_value_auth_type( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of auth type""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util(account.entity.auth_key.get_value, "basic") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_list_auth_type( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies auth type list dropdown""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util( + account.entity.auth_key.list_of_values(), + ["Basic Authentication", "OAuth 2.0 Authentication"], + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_checked_example_checkbox( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies Check/Uncheck in example checkbox""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.example_checkbox.check() + self.assert_util(account.entity.example_checkbox.is_checked, True) + account.entity.example_checkbox.uncheck() + self.assert_util(account.entity.example_checkbox.is_checked, False) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_select_value_example_environment( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example environment select value""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.environment.select("Value2") + self.assert_util(account.entity.environment.get_value, "Value2") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_list_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example multiple select list dropdown""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util( + account.entity.multiple_select.list_of_values(), + ["Option One", "Option Two"], + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_select_value_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies exampl multiple select value""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.multiple_select.select("Option One") + account.entity.multiple_select.select("Option Two") + self.assert_util( + account.entity.multiple_select.get_values, ["Option One", "Option Two"] + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_search_value_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies exampl multiple select seach funtionality""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util( + account.entity.multiple_select.search_get_list, + ["Option One"], + left_args={"value": "Option One"}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_default_value_example_radio( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of example radio""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + self.assert_util(account.entity.account_radio.get_value, "Yes") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_add_account_duplicate_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies by saving an entity with duplicate name at time of add it displays and error""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.multiple_select.select("Option One") + account.entity.username.set_value(ACCOUNT_CONFIG["username"]) + account.entity.password.set_value(ACCOUNT_CONFIG["password"]) + account.entity.account_radio.select("Yes") + self.assert_util( + account.entity.save, + "Name {} is already in use".format(ACCOUNT_CONFIG["name"]), + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_delete_row_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the frontend delete functionlity""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.delete_row(ACCOUNT_CONFIG["name"]) + account.table.wait_for_rows_to_appear(0) + self.assert_util(ACCOUNT_CONFIG["name"], account.table.get_table, "not in") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_edit_uneditable_field_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the frontend uneditable fields at time of edit of the account""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.edit_row(ACCOUNT_CONFIG["name"]) + self.assert_util(account.entity.name.is_editable, False) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_credentials_encrypted_value( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the default number of rows in the table""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.wait_for_rows_to_appear(1) + assert account.backend_conf.get_stanza(ACCOUNT_CONFIG["name"]) == { + "account_checkbox": "1", + "account_multiple_select": ACCOUNT_CONFIG["account_multiple_select"], + "account_radio": "1", + "auth_type": ACCOUNT_CONFIG["auth_type"], + "username": ACCOUNT_CONFIG["username"], + "custom_endpoint": ACCOUNT_CONFIG["custom_endpoint"], + "disabled": False, + "password": "******", + "token": "******", + } + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_add_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the frontend after adding account""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.username.set_value(ACCOUNT_CONFIG["username"]) + account.entity.multiple_select.select("Option One") + account.entity.password.set_value(ACCOUNT_CONFIG["password"]) + account.entity.security_token.set_value("TestToken") + self.assert_util(account.entity.save, True) + account.table.wait_for_rows_to_appear(1) + self.assert_util( + account.table.get_table()[ACCOUNT_CONFIG["name"]], + { + "name": ACCOUNT_CONFIG["name"], + "auth type": "basic", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_edit_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the frontend edit functionality""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.edit_row(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, True) + account.table.wait_for_rows_to_appear(1) + self.assert_util( + account.table.get_table()[ACCOUNT_CONFIG["name"]], + { + "name": "TestAccount", + "auth type": "basic", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_clone_account_duplicate_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies by saving an entity with duplicate name at time of clone it displays and error""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.clone_row(ACCOUNT_CONFIG["name"]) + account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + self.assert_util( + account.entity.save, + "Name {} is already in use".format(ACCOUNT_CONFIG["name"]), + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_clone_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the frontend clone functionality""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.wait_for_rows_to_appear(1) + account.table.clone_row(ACCOUNT_CONFIG["name"]) + account.entity.name.set_value("TestAccount2") + account.entity.username.set_value("TestUserClone") + account.entity.password.set_value("TestPasswordClone") + account.entity.security_token.set_value("TestTokenClone") + account.entity.account_radio.select("Yes") + self.assert_util(account.entity.save, True) + self.assert_util( + account.table.get_table()["TestAccount2"], + { + "name": "TestAccount2", + "auth type": "basic", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_clone_default_values( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the frontend default fields at time of clone""" + 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.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") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_add_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the account in backend after adding account from frontend""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.entity.open() + account.entity.name.set_value(ACCOUNT_CONFIG["name"]) + account.entity.username.set_value(ACCOUNT_CONFIG["username"]) + account.entity.multiple_select.select("Option One") + account.entity.password.set_value(ACCOUNT_CONFIG["password"]) + account.entity.security_token.set_value(ACCOUNT_CONFIG["token"]) + self.assert_util(account.entity.save, True) + account.table.wait_for_rows_to_appear(1) + assert account.backend_conf.get_stanza( + ACCOUNT_CONFIG["name"], decrypt=True + ) == { + "account_multiple_select": ACCOUNT_CONFIG["account_multiple_select"], + "account_radio": "1", + "auth_type": ACCOUNT_CONFIG["auth_type"], + "username": ACCOUNT_CONFIG["username"], + "custom_endpoint": ACCOUNT_CONFIG["custom_endpoint"], + "disabled": False, + "password": ACCOUNT_CONFIG["password"], + "token": ACCOUNT_CONFIG["token"], + } + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_edit_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """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.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") + account.entity.save() + account.table.wait_for_rows_to_appear(1) + assert account.backend_conf.get_stanza( + ACCOUNT_CONFIG["name"], decrypt=True + ) == { + "account_checkbox": "1", + "account_multiple_select": "one,two", + "account_radio": "0", + "auth_type": "basic", + "username": "TestEditUser", + "custom_endpoint": "login.example.com", + "disabled": False, + "password": "TestEditPassword", + "token": "TestEditToken", + } + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_clone_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the account in backend after cloning account from frontend""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.wait_for_rows_to_appear(1) + account.table.clone_row(ACCOUNT_CONFIG["name"]) + account.entity.name.set_value("TestAccountClone") + account.entity.multiple_select.select("Option Two") + account.entity.username.set_value("TestCloneUser") + account.entity.password.set_value("TestEditPassword") + account.entity.security_token.set_value("TestEditToken") + account.entity.account_radio.select("No") + account.entity.save() + account.table.wait_for_rows_to_appear(2) + assert account.backend_conf.get_stanza("TestAccountClone", decrypt=True) == { + "account_checkbox": "1", + "account_multiple_select": "one,two", + "account_radio": "0", + "auth_type": "basic", + "username": "TestCloneUser", + "custom_endpoint": "login.example.com", + "disabled": False, + "password": "TestEditPassword", + "token": "TestEditToken", + } + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + @pytest.mark.sanity_test + def test_account_delete_row_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account + ): + """Verifies the account in backend after deleting the account from frontend""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + account.table.delete_row(ACCOUNT_CONFIG["name"]) + account.table.wait_for_rows_to_appear(0) + self.assert_util( + ACCOUNT_CONFIG["name"], + account.backend_conf.get_all_stanzas().keys(), + "not in", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_helplink(self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper): + """Verifies whether the table help link redirects to the correct URL""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + go_to_link = "https://docs.splunk.com/Documentation" + account.entity.open() + with account.entity.help_link.open_link() as link_url: + self.assert_util(account.entity.help_link.get_current_url, go_to_link) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.account + def test_account_delete_account_in_use( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_account, add_input + ): + """Verifies by deleting the input used account""" + account = AccountPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + account.table.delete_row, + r'Are you sure you want to delete "TestAccount" ? Ensure that no input is configured with "TestAccount" as this will stop data collection for that input.', + left_args={"name": ACCOUNT_CONFIG["name"], "prompt_msg": True}, + ) diff --git a/tests/ui/test_splunk_ta_example_addon_alert_actions.py b/tests/ui/test_splunk_ta_example_addon_alert_actions.py new file mode 100644 index 00000000..3c087be0 --- /dev/null +++ b/tests/ui/test_splunk_ta_example_addon_alert_actions.py @@ -0,0 +1,203 @@ +import pytest +from pytest_splunk_addon_ui_smartx.base_test import UccTester +from pytest_splunk_addon_ui_smartx.components.base_component import Selector +from pytest_splunk_addon_ui_smartx.components.controls.button import Button + +from .Example_UccLib.alert_action import AlertPage +from .test_splunk_ta_example_addon_input import add_account + + +@pytest.fixture(autouse=True) +def setup_alert(ucc_smartx_selenium_helper): + """ + Skip the popups in Splunk before executing the tests + """ + try: + # Splunk 8.x + if not setup_alert.first_execution: + return + AlertPage(ucc_smartx_selenium_helper, None, open_page=False) + intro_popup = Button( + ucc_smartx_selenium_helper.browser, + Selector(select=".modal-footer .btn-save"), + ) + intro_popup.wait_to_be_clickable() + intro_popup.click() + setup_alert.first_execution = False + + # Splunk 8.0.x + important_changes_coming = Button( + ucc_smartx_selenium_helper.browser, + Selector( + select='div[data-test-name="python3-notification-modal"] button[data-test="button"][data-appearance="secondary"]' + ), + ) + important_changes_coming.wait_to_be_clickable() + important_changes_coming.click() + except: + pass + + +setup_alert.first_execution = True + + +@pytest.fixture +def clean_alert(ucc_smartx_rest_helper): + yield None + + alert_page = AlertPage(None, ucc_smartx_rest_helper, open_page=False) + alert_page.backend_conf.delete_all_stanzas(query="search=test_alert") + + +class TestAlertActions(UccTester): + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_action_in_list(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + self.assert_util( + "Test Alert", + alert_page.alert_entity.add_action_dropdown.get_value_list, + "in", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_dropdown_list(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + + self.assert_util( + alert_page.action_entity.table_list.list_of_values, ["incident", "problem"] + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_account_functionality(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + + alert_page.action_entity.account.select("test_input") + alert_page.action_entity.account.wait_for_values() + self.assert_util(alert_page.action_entity.account.get_value, "test_input") + alert_page.action_entity.account.cancel_selected_value() + alert_page.action_entity.account.wait_for_values() + self.assert_util(alert_page.action_entity.account.get_value, "test_input", "!=") + self.assert_util( + "test_input", alert_page.action_entity.account.list_of_values, "in" + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_checkbox(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + + alert_page.action_entity.all_incident.toggle() + self.assert_util(alert_page.action_entity.all_incident.is_checked, True) + alert_page.action_entity.all_incident.toggle() + self.assert_util(alert_page.action_entity.all_incident.is_checked, False) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_single_select(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + + self.assert_util( + alert_page.action_entity.table_list.list_of_values, ["incident", "problem"] + ) + alert_page.action_entity.table_list.select("problem") + self.assert_util(alert_page.action_entity.table_list.get_value, "problem") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_toggle(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + + alert_page.action_entity.action.select("Delete") + assert alert_page.action_entity.action.get_value() == "Delete" + alert_page.action_entity.action.select("Update") + assert alert_page.action_entity.action.get_value() == "Update" + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.sanity_test + def test_alert_action_save(self, ucc_smartx_selenium_helper, clean_alert): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + + # Add Alert Configs + alert_page.alert_entity.name.set_value("test_alert") + alert_page.alert_entity.search.set_value("| search index=_internal" + "\ue007") + + # Open Action + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + + # Add Action Configs + alert_page.action_entity.name.set_value("test_action") + alert_page.action_entity.all_incident.toggle() + alert_page.action_entity.action.select("Delete") + alert_page.action_entity.account.select("test_input") + alert_page.alert_entity.save() + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_table.wait_for_rows_to_appear() + assert "test_alert" in alert_page.alert_table.get_column_values("name") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_alert_help_text_entity(self, ucc_smartx_selenium_helper): + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + self.assert_util( + alert_page.action_entity.name.get_help_text, "Please enter your name" + ) + self.assert_util( + alert_page.action_entity.all_incident.get_help_text, + "Tick if you want to update all incidents/problems", + ) + self.assert_util( + alert_page.action_entity.table_list.get_help_text, "Please select the table" + ) + self.assert_util( + alert_page.action_entity.action.get_help_text, + "Select the action you want to perform", + ) + self.assert_util( + alert_page.action_entity.account.get_help_text, + "Select the account from the dropdown", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + def test_alert_action_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the alert field labels""" + alert_page = AlertPage(ucc_smartx_selenium_helper, None) + alert_page.alert_entity.open() + alert_page.alert_entity.add_action_dropdown.wait_for_values() + alert_page.alert_entity.add_action_dropdown.select_action("Test Alert") + self.assert_util(alert_page.action_entity.name.get_input_label, "Name *") + self.assert_util( + alert_page.action_entity.table_list.get_input_label, "Table List" + ) + self.assert_util(alert_page.action_entity.action.get_input_label, "Action:") + self.assert_util( + alert_page.action_entity.account.get_input_label, "Select Account *" + ) diff --git a/tests/ui/test_splunk_ta_example_addon_custom.py b/tests/ui/test_splunk_ta_example_addon_custom.py new file mode 100644 index 00000000..3c45e3de --- /dev/null +++ b/tests/ui/test_splunk_ta_example_addon_custom.py @@ -0,0 +1,402 @@ +from pytest_splunk_addon_ui_smartx.base_test import UccTester +from .Example_UccLib.custom import Custom +import pytest + +DEFAULT_CONFIGURATION = { + "test_number": "", + "test_regex": "", + "test_string": "", + "test_email": "", + "test_ipv4": "", + "test_date": "", + "test_url": "", + "test_radio": "Yes", + "test_multiselect": "", +} + + +@pytest.fixture(autouse=True) +def reset_configuration(ucc_smartx_selenium_helper, ucc_smartx_rest_helper): + yield + custom = Custom(ucc_smartx_rest_helper=ucc_smartx_rest_helper) + custom.backend_conf.update_parameters(DEFAULT_CONFIGURATION) + + +class TestCustom(UccTester): + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_fields_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies custom fields label""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util(custom.test_string.get_input_label, "Test String") + self.assert_util(custom.test_number.get_input_label, "Test Number") + self.assert_util(custom.test_regex.get_input_label, "Test Regex") + self.assert_util(custom.test_email.get_input_label, "Test Email") + self.assert_util(custom.test_ipv4.get_input_label, "Test Ipv4") + self.assert_util(custom.test_date.get_input_label, "Test Date") + self.assert_util(custom.test_url.get_input_label, "Test Url") + self.assert_util(custom.test_radio.get_input_label, "Test Radio") + self.assert_util(custom.test_multiselect.get_input_label, "Test Multiselect") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_fields_placeholder_value( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies custom fields placeholder value""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util(custom.test_string.get_placeholder_value, "Required") + self.assert_util(custom.test_number.get_placeholder_value, "Required") + self.assert_util(custom.test_regex.get_placeholder_value, "optional") + self.assert_util(custom.test_email.get_placeholder_value, "optional") + self.assert_util(custom.test_ipv4.get_placeholder_value, "optional") + self.assert_util(custom.test_date.get_placeholder_value, "optional") + self.assert_util(custom.test_url.get_placeholder_value, "optional") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + @pytest.mark.sanity_test + def test_custom_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks the validates frontend save in custom tab""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("7") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("1.10.1.100") + custom.test_date.set_value("2020-09-18") + custom.test_url.set_value("https://docs.splunk.com/Documentation") + custom.test_radio.select("No") + custom.test_multiselect.select("Option A") + custom.test_multiselect.select("Option B") + self.assert_util(custom.save, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + @pytest.mark.sanity_test + def test_custom_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks the validates backend save in custom tab""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("7") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("1.10.1.100") + custom.test_date.set_value("2020-09-18") + custom.test_url.set_value("https://docs.splunk.com/Documentation") + custom.test_radio.select("No") + custom.test_multiselect.select("Option A") + custom.test_multiselect.select("Option B") + custom.save() + self.assert_util( + custom.backend_conf.get_stanza, + { + "disabled": False, + "test_number": "7", + "test_regex": "test_rex", + "test_string": "test_str", + "test_email": "test@a.b", + "test_ipv4": "1.10.1.100", + "test_date": "2020-09-18", + "test_url": "https://docs.splunk.com/Documentation", + "test_radio": "0", + "test_multiselect": "Option A|Option B", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_required_field_test_string( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks required field test string""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_number.set_value("7") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("1.10.1.100") + custom.test_date.set_value("2020-09-18") + custom.test_url.set_value("https://docs.splunk.com/Documentation") + custom.test_radio.select("No") + custom.test_multiselect.select("Option A") + self.assert_util( + custom.save, + r"Field Test String is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_length_test_string_greater( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks length of test string field should be greater than 4""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test") + self.assert_util( + custom.save, + r"Length of Test String should be greater than or equal to 5", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_length_test_string_less( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks length of test string field should be less than 11""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_string") + self.assert_util( + custom.save, + r"Length of Test String should be less than or equal to 10", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_required_field_test_number( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks required field test number""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("1.10.1.100") + custom.test_date.set_value("2020-09-18") + custom.test_url.set_value("https://docs.splunk.com/Documentation") + custom.test_radio.select("No") + custom.test_multiselect.select("Option A") + self.assert_util( + custom.save, + r"Field Test Number is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_input_test_number( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks test number field should be interger""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("a") + self.assert_util( + custom.save, + r"Field Test Number is not a number", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_range_test_number( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks range of test number field should be between 1 to 10""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("50") + self.assert_util( + custom.save, + r"Field Test Number should be within the range of [1 and 10]", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_input_test_regex( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks regex of test regex field""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("5") + custom.test_regex.set_value("$$") + self.assert_util( + custom.save, + r"Characters of Name should match regex ^\w+$ .", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_input_test_email( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks test email field should be email""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("5") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("abc") + self.assert_util( + custom.save, + r"Field Test Email is not a valid email address", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_input_test_ipv4( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks test ipv4 field should be valid ipv4""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("5") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("10.1.11") + self.assert_util( + custom.save, + r"Field Test Ipv4 is not a valid IPV4 address", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_input_test_date( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks test date field should be in ISO 8601 format""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("5") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("10.1.11.1") + custom.test_date.set_value("20-10-2020") + self.assert_util( + custom.save, + r"Field Test Date is not a valid date in ISO 8601 format", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_valid_input_test_url( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks test url field should be valid url""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_string.set_value("test_str") + custom.test_number.set_value("5") + custom.test_regex.set_value("test_rex") + custom.test_email.set_value("test@a.b") + custom.test_ipv4.set_value("10.1.11.1") + custom.test_date.set_value("2020-09-18") + custom.test_url.set_value("\\\\") + self.assert_util( + custom.save, + r"Field Test Url is not a valid URL", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_select_value_test_radio( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks selected value of test radio""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + custom.test_radio.select("No") + self.assert_util(custom.test_radio.get_value, r"No") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_list_test_multiselect( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks values of Multiple Select Test dropdown""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + test_multiselect = ["Option A", "Option B"] + self.assert_util(custom.test_multiselect.list_of_values(), test_multiselect) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_select_value_test_multiselect( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks selected single value of Multiple Select Test dropdown""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_values = ["Option A"] + for each in selected_values: + custom.test_multiselect.select(each) + self.assert_util(custom.test_multiselect.get_values, selected_values) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_select_multiple_values_test_multiselect( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks selected multiple values of Multiple Select Test dropdown""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_values = ["Option A", "Option B"] + for each in selected_values: + custom.test_multiselect.select(each) + self.assert_util(custom.test_multiselect.get_values, selected_values) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_search_value_test_multiselect( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks multiple select seach funtionality""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + custom.test_multiselect.search_get_list, + ["Option A"], + left_args={"value": "Option A"}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_deselect_test_multiselect( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks deselect funtionality of multiple select""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_values = ["Option A", "Option B"] + for each in selected_values: + custom.test_multiselect.select(each) + custom.test_multiselect.deselect("Option A") + self.assert_util(custom.test_multiselect.get_values, ["Option B"]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.custom + def test_custom_help_link(self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper): + """This test case checks whether help link redirects to the correct URL""" + custom = Custom(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + go_to_link = "https://docs.splunk.com/Documentation" + with custom.test_help_link.open_link() as link_url: + self.assert_util(custom.test_help_link.get_current_url, go_to_link) diff --git a/tests/ui/test_splunk_ta_example_addon_input.py b/tests/ui/test_splunk_ta_example_addon_input.py new file mode 100644 index 00000000..55e1a6ee --- /dev/null +++ b/tests/ui/test_splunk_ta_example_addon_input.py @@ -0,0 +1,2348 @@ +from pytest_splunk_addon_ui_smartx.base_test import UccTester +from .Example_UccLib.account import AccountPage +from .Example_UccLib.input_page import InputPage +import pytest + + +@pytest.fixture(scope="module", autouse=True) +def add_account(ucc_smartx_rest_helper): + account = AccountPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = account._get_account_endpoint() + kwargs = { + "name": "test_input", + "account_checkbox": 1, + "account_multiple_select": "one", + "account_radio": "yes", + "auth_type": "basic", + "custom_endpoint": "login.example.com", + "username": "TestUser", + "password": "TestPassword", + "token": "TestToken", + "client_id": "", + "client_secret": "", + "redirect_url": "", + "endpoint": "", + "example_help_link": "", + } + yield account.backend_conf.post_stanza(url, kwargs) + account.backend_conf.delete_all_stanzas() + + +@pytest.fixture +def add_multiple_inputs(ucc_smartx_rest_helper): + input_page = InputPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = input_page._get_input_endpoint() + for i in range(50): + kwargs = { + "name": "example_input_one://dummy_input_one" + str(i), + "account": "test_input", + "input_one_checkbox": "1", + "input_one_radio": "yes", + "interval": "90", + "limit": "1000", + "multipleSelectTest": "a|b", + "object": "test_object", + "object_fields": "test_field", + "order_by": "LastModifiedDate", + "singleSelectTest": "two", + "start_date": "2020-12-11T20:00:32.000z", + "disabled": 0, + } + input_page.backend_conf.post_stanza(url, kwargs) + kwargs = { + "name": "example_input_two://dummy_input_two" + str(i), + "account": "test_input", + "input_two_checkbox": "1", + "input_two_radio": "no", + "interval": "100", + "input_two_multiple_select": "one,two", + "index": "main", + "start_date": "2016-10-10T12:10:15.000z", + "disabled": 0, + } + input_page.backend_conf.post_stanza(url, kwargs) + + +@pytest.fixture +def add_input_one(ucc_smartx_rest_helper): + input_page = InputPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = input_page._get_input_endpoint() + kwargs = { + "name": "example_input_one://dummy_input_one", + "account": "test_input", + "input_one_checkbox": "1", + "input_one_radio": "yes", + "interval": "90", + "limit": "1000", + "multipleSelectTest": "a|b", + "object": "test_object", + "object_fields": "test_field", + "order_by": "LastModifiedDate", + "singleSelectTest": "two", + "start_date": "2020-12-11T20:00:32.000z", + "disabled": 0, + } + yield input_page.backend_conf.post_stanza(url, kwargs) + + +@pytest.fixture +def add_input_two(ucc_smartx_rest_helper): + input_page = InputPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + url = input_page._get_input_endpoint() + kwargs = { + "name": "example_input_two://dummy_input_two", + "account": "test_input", + "input_two_checkbox": "1", + "input_two_radio": "no", + "interval": "100", + "input_two_multiple_select": "one,two", + "index": "main", + "start_date": "2016-10-10T12:10:15.000z", + "disabled": 0, + } + yield input_page.backend_conf.post_stanza(url, kwargs) + + +@pytest.fixture(autouse=True) +# All the inputs created shoud start with dummy_input as prefix +def delete_inputs(ucc_smartx_rest_helper): + yield + input_page = InputPage( + ucc_smartx_rest_helper=ucc_smartx_rest_helper, open_page=False + ) + input_page.backend_conf.delete_all_stanzas("search=dummy_input") + + +class TestInput(UccTester): + + ############################ + ### TEST CASES FOR TABLE ### + ############################ + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_displayed_columns( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies headers of input table""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + header_list = ["Name", "Account", "Interval", "Index", "Status", "Actions"] + self.assert_util(input_page.table.get_headers, header_list) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_pagination_list( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies pagination list""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.pagination.get_pagination_list, + ["10 Per Page", "25 Per Page", "50 Per Page"], + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_pagination( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_multiple_inputs + ): + """Verifies pagination functionality by creating 100 accounts""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.open() + self.assert_util( + input_page.pagination.select_page_option, + True, + left_args={"value": "50 Per Page"}, + ) + self.assert_util(input_page.table.switch_to_page, True, left_args={"value": 2}) + self.assert_util(input_page.table.switch_to_prev, True) + self.assert_util(input_page.table.switch_to_next, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_sort_functionality( + self, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + add_input_one, + add_input_two, + ): + """Verifies sorting functionality for name column""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.pagination.select_page_option("50 Per Page") + input_page.table.sort_column("Name") + sort_order = input_page.table.get_sort_order() + column_values = list(input_page.table.get_column_values("Name")) + column_values = list(str(item) for item in column_values) + sorted_values = sorted(column_values, key=str.lower) + self.assert_util(sort_order["header"].lower(), "name") + self.assert_util(column_values, sorted_values) + self.assert_util(sort_order["ascending"], True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_filter_functionality_negative( + self, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + add_input_one, + add_input_two, + ): + """Verifies the filter functionality (Negative)""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.set_filter("hello") + self.assert_util(input_page.table.get_row_count, 0) + self.assert_util( + input_page.table.get_count_title, + "{} Input".format(input_page.table.get_row_count()), + ) + input_page.table.clean_filter() + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_filter_functionality_positive( + self, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + add_input_one, + add_input_two, + ): + """Verifies the filter functionality (Positive)""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.set_filter("dummy") + self.assert_util(input_page.table.get_row_count, 2) + self.assert_util( + input_page.table.get_count_title, + "{} Inputs".format(input_page.table.get_row_count()), + ) + input_page.table.clean_filter() + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_default_rows_in_table( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the default number of rows in the table""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util(input_page.table.get_row_count, 0) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_create_new_input_list_values( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies input list dropdown""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + create_new_input_list = ["Example Input One", "Example Input Two"] + self.assert_util( + input_page.create_new_input.get_inputs_list, create_new_input_list + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_input_type_list_values( + self, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + add_input_one, + add_input_two, + ): + """Verifies input type filter list""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + type_filter_list = ["All", "Example Input One", "Example Input Two"] + self.assert_util(input_page.type_filter.get_input_type_list, type_filter_list) + input_page.type_filter.select_input_type( + "Example Input One", open_dropdown=False + ) + self.assert_util(input_page.table.get_row_count, 1) + input_page.type_filter.select_input_type("Example Input Two") + self.assert_util(input_page.table.get_row_count, 1) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_delete_enabled_input( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies enabled input should not delete""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.delete_row, + r"Can't delete enabled input", + left_args={"name": "dummy_input_one"}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_more_info( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the expand functionality of the inputs table""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.get_more_info, + { + "Name": "dummy_input_one", + "Interval": "90", + "Index": "default", + "Status": "Enabled", + "Example Account": "test_input", + "Object": "test_object", + "Object Fields": "test_field", + "Order By": "LastModifiedDate", + "Query Start Date": "2020-12-11T20:00:32.000z", + "Limit": "1000", + }, + left_args={"name": "dummy_input_one"}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_enable_disable( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the enable and disable functionality of the input""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.input_status_toggle, + True, + left_args={"name": "dummy_input_one", "enable": False}, + ) + self.assert_util( + input_page.table.input_status_toggle, + True, + left_args={"name": "dummy_input_one", "enable": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_count( + self, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + add_input_one, + add_input_two, + ): + """Verifies count on table""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.get_count_title, + "{} Inputs".format(input_page.table.get_row_count()), + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_inputs_title_and_description( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the title and description of the page""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util(input_page.title.wait_to_display, "Inputs") + self.assert_util( + input_page.description.wait_to_display, "Manage your data inputs" + ) + + ########################################## + #### TEST CASES FOR EXAMPLE INPUT ONE #### + ########################################## + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field name in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("two") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity1.save, + r"Field Name is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_valid_length_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the name field should not be more than 100 characters""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + name_value = "a" * 101 + input_page.entity1.name.set_value(name_value) + self.assert_util( + input_page.entity1.save, + r"Length of input name should be between 1 and 100", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_valid_input_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether adding special characters, name field displays validation error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("$$test_name") + self.assert_util( + input_page.entity1.save, + r"Input Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_list_single_select_group_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies values Single Select Group Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + single_select_group_test_list = ["One", "Two", "Three", "Four"] + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util( + input_page.entity1.single_select_group_test.list_of_values(), + single_select_group_test_list, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_select_value_single_select_group_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies selected value of Single Select Group Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_value = "Two" + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.single_select_group_test.select(selected_value) + self.assert_util( + input_page.entity1.single_select_group_test.get_value, selected_value + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_search_value_single_select_group_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies singleselect seach funtionality properly""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util( + input_page.entity1.single_select_group_test.search_get_list, + ["one", "One"], + left_args={"value": "one"}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_default_value_multiple_select_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default values of Multiple Select Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + default_values = ["A", "B"] + self.assert_util( + input_page.entity1.multiple_select_test.get_values, default_values + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_list_multiple_select_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies values of Multiple Select Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.multiple_select_test.deselect_all() + multiple_select_test = ["A", "B"] + self.assert_util( + input_page.entity1.multiple_select_test.list_of_values(), + multiple_select_test, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_select_value_multiple_select_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies selected single value of Multiple Select Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_value = ["A"] + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.multiple_select_test.deselect_all() + for each in selected_value: + input_page.entity1.multiple_select_test.select(each) + self.assert_util( + input_page.entity1.multiple_select_test.get_values, selected_value + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_select_multiple_values_multiple_select_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies selected multiple values of Multiple Select Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_values = ["A", "B"] + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.multiple_select_test.deselect_all() + for each in selected_values: + input_page.entity1.multiple_select_test.select(each) + self.assert_util( + input_page.entity1.multiple_select_test.get_values, selected_values + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_deselect_multiple_select_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies deselect in Multiple Select Test dropdown in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_values = ["A", "B"] + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.multiple_select_test.deselect_all() + for each in selected_values: + input_page.entity1.multiple_select_test.select(each) + input_page.entity1.multiple_select_test.deselect("A") + self.assert_util(input_page.entity1.multiple_select_test.get_values, ["B"]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_search_value_multiple_select_test( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies multiple select seach funtionality properly""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.multiple_select_test.deselect_all() + self.assert_util( + input_page.entity1.multiple_select_test.search_get_list, + ["A"], + left_args={"value": "A"}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_default_value_example_checkbox( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of example checkbox in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.example_checkbox.is_checked, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_unchecked_example_checkbox( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies Uncheck in example checkbox in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_checkbox.check() + self.assert_util(input_page.entity1.example_checkbox.uncheck, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_checked_example_checkbox( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies checked in example checkbox in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_checkbox.uncheck() + self.assert_util(input_page.entity1.example_checkbox.check, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_default_value_example_radio( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of example radio in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.example_radio.get_value, "Yes") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_select_value_example_radio( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies selected value of example radio in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_radio.select("No") + self.assert_util(input_page.entity1.example_radio.get_value, "No") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_interval( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field interval in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity1.save, + r"Field Interval is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_valid_input_interval( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether adding non numeric values, intreval field displays validation error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.name.set_value("test_name") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.interval.set_value("abc") + self.assert_util( + input_page.entity1.save, + r"Interval must be an integer.", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_index( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field index in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + input_page.entity1.index.cancel_selected_value() + self.assert_util( + input_page.entity1.save, + r"Field Index is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_default_value_index( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of field index in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + default_index = "default" + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.index.get_value, default_index) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_example_account( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field Salesforce Account in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.interval.set_value("90") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity1.save, + r"Field Example Account is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_object( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field Object in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity1.save, + r"Field Object is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_object_fields( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field Object Fields in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity1.save, + r"Field Object Fields is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_required_field_order_by( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field Order By in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + input_page.entity1.order_by.set_value("") + self.assert_util( + input_page.entity1.save, + r"Field Order By is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_default_value_order_by( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of field Order By in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + default_order_by = "LastModifiedDate" + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.order_by.get_value, default_order_by) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_fields_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example input one field label""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + self.assert_util(input_page.entity1.name.get_input_label, "Name") + self.assert_util( + input_page.entity1.example_checkbox.get_input_label, "Example Checkbox" + ) + self.assert_util( + input_page.entity1.example_radio.get_input_label, "Example Radio" + ) + self.assert_util( + input_page.entity1.single_select_group_test.get_input_label, + "Single Select Group Test", + ) + self.assert_util( + input_page.entity1.multiple_select_test.get_input_label, + "Multiple Select Test", + ) + self.assert_util(input_page.entity1.interval.get_input_label, "Interval") + self.assert_util(input_page.entity1.index.get_input_label, "Index") + self.assert_util( + input_page.entity1.example_account.get_input_label, "Example Account" + ) + self.assert_util(input_page.entity1.object.get_input_label, "Object") + self.assert_util( + input_page.entity1.object_fields.get_input_label, "Object Fields" + ) + self.assert_util(input_page.entity1.order_by.get_input_label, "Order By") + self.assert_util( + input_page.entity1.query_start_date.get_input_label, "Query Start Date" + ) + self.assert_util(input_page.entity1.limit.get_input_label, "Limit") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_fields_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example input two field label""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + self.assert_util(input_page.entity2.name.get_input_label, "Name") + self.assert_util(input_page.entity2.interval.get_input_label, "Interval") + self.assert_util(input_page.entity2.index.get_input_label, "Index") + self.assert_util( + input_page.entity2.example_account.get_input_label, "Example Account" + ) + self.assert_util( + input_page.entity2.example_multiple_select.get_input_label, + "Example Multiple Select", + ) + self.assert_util( + input_page.entity2.example_checkbox.get_input_label, "Example Checkbox" + ) + self.assert_util( + input_page.entity2.example_radio.get_input_label, "Example Radio" + ) + self.assert_util( + input_page.entity2.query_start_date.get_input_label, "Query Start Date" + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_fields_placeholder_value( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example input one field placeholder value""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + self.assert_util( + input_page.entity1.query_start_date.get_placeholder_value, "optional" + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_fields_placeholder_value( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies example input two field placeholder value""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + self.assert_util( + input_page.entity1.query_start_date.get_placeholder_value, "optional" + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_help_text_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies help text for the field name""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util( + input_page.entity1.name.get_help_text, "A unique name for the data input." + ) + self.assert_util( + input_page.entity1.example_checkbox.get_help_text, + "This is an example checkbox for the input one entity", + ) + self.assert_util( + input_page.entity1.example_radio.get_help_text, + "This is an example radio button for the input one entity", + ) + self.assert_util( + input_page.entity1.interval.get_help_text, + "Time interval of the data input, in seconds.", + ) + self.assert_util( + input_page.entity1.object.get_help_text, + "The name of the object to query for.", + ) + self.assert_util( + input_page.entity1.object_fields.get_help_text, + "Object fields from which to collect data. Delimit multiple fields using a comma.", + ) + self.assert_util( + input_page.entity1.query_start_date.get_help_text, + 'The datetime after which to query and index records, in this format: "YYYY-MM-DDThh:mm:ss.000z". Defaults to 90 days earlier from now.', + ) + self.assert_util( + input_page.entity1.limit.get_help_text, + "The maximum number of results returned by the query.", + ) + self.assert_util( + input_page.entity1.order_by.get_help_text, + "The datetime field by which to query results in ascending order for indexing.", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_valid_input_query_start_date( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether adding wrong format, Query Start Date field displays validation error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("test_name") + input_page.entity1.interval.set_value("120") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_object_field") + input_page.entity1.query_start_date.set_value("2020/01/01") + self.assert_util( + input_page.entity1.save, + r"Invalid date and time format", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_default_value_limit( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of field limit in example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + default_limit = "1000" + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.limit.get_value, default_limit) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_help_link( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether the help link redirects to the correct URL""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + go_to_link = "https://docs.splunk.com/Documentation" + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + with input_page.entity1.help_link.open_link() as link_url: + self.assert_util(input_page.entity1.help_link.get_current_url, go_to_link) + + ################################### + #### TEST CASES FOR ENTITY ONE #### + ################################### + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_add_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the frontend after adding a Example Input One""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("Yes") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util(input_page.entity1.save, True) + input_page.table.wait_for_rows_to_appear(1) + self.assert_util( + input_page.table.get_table()["dummy_input"], + { + "name": "dummy_input", + "account": "test_input", + "interval": "90", + "index": "default", + "status": "Enabled", + "actions": "Edit | Clone | Delete", + }, + ) + + url = input_page._get_input_endpoint() + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_add_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the backend after adding a example input one""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input") + input_page.entity1.example_radio.select("No") + input_page.entity1.single_select_group_test.select("Two") + input_page.entity1.interval.set_value("90") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("test_object") + input_page.entity1.object_fields.set_value("test_field") + input_page.entity1.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util(input_page.entity1.save, True) + input_page.table.wait_for_rows_to_appear(1) + value_to_test = { + "account": "test_input", + "input_one_checkbox": "1", + "input_one_radio": "0", + "interval": "90", + "limit": "1000", + "multipleSelectTest": "a|b", + "object": "test_object", + "object_fields": "test_field", + "order_by": "LastModifiedDate", + "singleSelectTest": "two", + "start_date": "2020-12-11T20:00:32.000z", + "disabled": 0, + } + backend_stanza = input_page.backend_conf.get_stanza( + "example_input_one://dummy_input" + ) + for each_key, each_value in value_to_test.items(): + assert each_key in backend_stanza + self.assert_util( + each_value, + backend_stanza[each_key], + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_edit_uneditable_field_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the frontend uneditable fields at time of edit of the example input one entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_one") + self.assert_util(input_page.entity1.name.is_editable, False) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_edit_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the frontend edit functionality of the example input one entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_one") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_checkbox.uncheck() + input_page.entity1.example_radio.select("No") + input_page.entity1.single_select_group_test.select("four") + input_page.entity1.multiple_select_test.deselect("b") + input_page.entity1.interval.set_value("3600") + input_page.entity1.index.select("main") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("edit_object") + input_page.entity1.object_fields.set_value("edit_field") + input_page.entity1.order_by.set_value("LastDate") + input_page.entity1.limit.set_value("2000") + input_page.entity1.query_start_date.set_value("2020-20-20T20:20:20.000z") + self.assert_util(input_page.entity1.save, True) + input_page.table.wait_for_rows_to_appear(1) + self.assert_util( + input_page.table.get_table()["dummy_input_one"], + { + "name": "dummy_input_one", + "account": "test_input", + "interval": "3600", + "index": "main", + "status": "Enabled", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_edit_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the backend edit functionality of the example input one entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_one") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.example_checkbox.uncheck() + input_page.entity1.example_radio.select("No") + input_page.entity1.single_select_group_test.select("Four") + input_page.entity1.multiple_select_test.deselect("b") + input_page.entity1.interval.set_value("3600") + input_page.entity1.index.select("main") + input_page.entity1.example_account.select("test_input") + input_page.entity1.object.set_value("edit_object") + input_page.entity1.object_fields.set_value("edit_field") + input_page.entity1.order_by.set_value("LastDate") + input_page.entity1.limit.set_value("2000") + input_page.entity1.query_start_date.set_value("2020-20-20T20:20:20.000z") + self.assert_util(input_page.entity1.save, True) + input_page.table.wait_for_rows_to_appear(1) + value_to_test = { + "account": "test_input", + "input_one_checkbox": "0", + "input_one_radio": "0", + "interval": "3600", + "index": "main", + "limit": "2000", + "multipleSelectTest": "a", + "object": "edit_object", + "object_fields": "edit_field", + "order_by": "LastDate", + "singleSelectTest": "four", + "start_date": "2020-20-20T20:20:20.000z", + "disabled": 0, + } + backend_stanza = input_page.backend_conf.get_stanza( + "example_input_one://dummy_input_one" + ) + for each_key, each_value in value_to_test.items(): + self.assert_util(each_value, backend_stanza[each_key]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_clone_default_values( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the frontend default fields at time of clone for example input one entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_one") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.name.get_value, "") + self.assert_util(input_page.entity1.example_checkbox.is_checked, True) + self.assert_util(input_page.entity1.example_radio.get_value, "Yes") + self.assert_util(input_page.entity1.single_select_group_test.get_value, "Two") + self.assert_util(input_page.entity1.multiple_select_test.get_values, ["A", "B"]) + self.assert_util(input_page.entity1.interval.get_value, "90") + self.assert_util(input_page.entity1.index.get_value, "default") + self.assert_util(input_page.entity1.example_account.get_value, "test_input") + self.assert_util(input_page.entity1.object.get_value, "test_object") + self.assert_util(input_page.entity1.object_fields.get_value, "test_field") + self.assert_util(input_page.entity1.order_by.get_value, "LastModifiedDate") + self.assert_util( + input_page.entity1.query_start_date.get_value, "2020-12-11T20:00:32.000z" + ) + self.assert_util(input_page.entity1.limit.get_value, "1000") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_clone_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the frontend clone functionality of the example input one entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.wait_for_rows_to_appear(1) + input_page.table.clone_row("dummy_input_one") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input_one_Clone_Test") + input_page.entity1.interval.set_value("180") + input_page.entity1.limit.set_value("500") + self.assert_util(input_page.entity1.save, True) + input_page.table.wait_for_rows_to_appear(2) + self.assert_util( + input_page.table.get_table()["dummy_input_one_Clone_Test"], + { + "name": "dummy_input_one_Clone_Test", + "account": "test_input", + "interval": "180", + "index": "default", + "status": "Enabled", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_clone_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the backend clone functionality of the example input one entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.wait_for_rows_to_appear(1) + input_page.table.clone_row("dummy_input_one") + input_page.entity1.example_account.wait_for_values() + input_page.entity1.name.set_value("dummy_input_one_Clone_Test") + input_page.entity1.interval.set_value("180") + input_page.entity1.limit.set_value("500") + self.assert_util(input_page.entity1.save, True) + input_page.table.wait_for_rows_to_appear(2) + value_to_test = { + "account": "test_input", + "input_one_checkbox": "1", + "input_one_radio": "1", + "interval": "180", + "index": "default", + "limit": "500", + "multipleSelectTest": "a|b", + "object": "test_object", + "object_fields": "test_field", + "order_by": "LastModifiedDate", + "singleSelectTest": "two", + "start_date": "2020-12-11T20:00:32.000z", + "disabled": 0, + } + backend_stanza = input_page.backend_conf.get_stanza( + "example_input_one://dummy_input_one_Clone_Test" + ) + for each_key, each_value in value_to_test.items(): + self.assert_util(each_value, backend_stanza[each_key]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_delete_row_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the frontend delete functionlity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.input_status_toggle("dummy_input_one", enable=False) + input_page.table.delete_row("dummy_input_one") + input_page.table.wait_for_rows_to_appear(0) + self.assert_util("dummy_input_one", input_page.table.get_table, "not in") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_one_delete_row_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the backend delete functionlity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.input_status_toggle("dummy_input_one", enable=False) + input_page.table.delete_row("dummy_input_one") + input_page.table.wait_for_rows_to_appear(0) + self.assert_util( + "example_input_one://dummy_input_one", + input_page.backend_conf.get_all_stanzas().keys(), + "not in", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_add_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies close functionality at time of add""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_edit_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies close functionality at time of edit""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_one") + self.assert_util(input_page.entity1.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_clone_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies close functionality at time of clone""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_one") + self.assert_util(input_page.entity1.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_delete_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies close functionality at time of delete""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.delete_row, + True, + left_args={"name": "dummy_input_one", "close": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_add_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies cancel functionality at time of add""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util(input_page.entity1.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_edit_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies cancel functionality at time of edit""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_one") + self.assert_util(input_page.entity1.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_clone_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies cancel functionality at time of clone""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_one") + self.assert_util(input_page.entity1.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_delete_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies cancel functionality at time of delete""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.delete_row, + True, + left_args={"name": "dummy_input_one", "cancel": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_add_duplicate_names( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies by saving an entity with duplicate name it displays and error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + input_name = "dummy_input_one" + input_page.entity1.name.set_value(input_name) + self.assert_util( + input_page.entity1.save, + "Name {} is already in use".format(input_name), + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_clone_duplicate_names( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies by saving an entity with duplicate name at time of clone it displays and error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_one") + input_page.entity1.example_account.wait_for_values() + input_name = "dummy_input_one" + input_page.entity1.name.set_value(input_name) + self.assert_util( + input_page.entity1.save, + "Name {} is already in use".format(input_name), + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_add_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the title of the 'Add Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input One") + input_page.entity1.example_account.wait_for_values() + self.assert_util( + input_page.entity1.title.container.get_attribute("textContent").strip(), + "Add Example Input One", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_edit_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the title of the 'Edit Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_one") + self.assert_util( + input_page.entity1.title.container.get_attribute("textContent").strip(), + "Update Example Input One", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_clone_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the title of the 'Clone Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_one") + self.assert_util( + input_page.entity1.title.container.get_attribute("textContent").strip(), + "Clone Example Input One", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_delete_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the title of the 'Delete Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.delete_row("dummy_input_one", prompt_msg=True) + self.assert_util( + input_page.entity1.title.container.get_attribute("textContent").strip(), + "Delete Confirmation", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_one_delete_valid_prompt_message( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one + ): + """Verifies the prompt message of the 'Delete Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_name = "dummy_input_one" + prompt_message = input_page.table.delete_row("dummy_input_one", prompt_msg=True) + self.assert_util( + prompt_message, 'Are you sure you want to delete "{}" ?'.format(input_name) + ) + + ########################################## + #### TEST CASES FOR EXAMPLE INPUT TWO #### + ########################################## + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_required_field_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field name in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.example_checkbox.check() + input_page.entity2.example_radio.select("No") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.index.select("main") + input_page.entity2.interval.set_value("90") + input_page.entity2.example_account.select("test_input") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity2.save, + r"Field Name is required", + left_args={"expect_error": True}, + ) + input_page.entity2.name.set_value("test_name_two") + self.assert_util(input_page.entity2.is_error_closed, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_valid_length_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the name field should not be more than 100 characters""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + name_value = "a" * 101 + input_page.entity2.name.set_value(name_value) + self.assert_util( + input_page.entity2.save, + r"Length of input name should be between 1 and 100", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_valid_input_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether adding special characters, name field displays validation error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("$$test_name_two") + self.assert_util( + input_page.entity2.save, + r"Input Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_required_field_interval( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field interval in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_radio.select("No") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.index.select("main") + input_page.entity2.example_account.select("test_input") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity2.save, + r"Field Interval is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_valid_input_interval( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether adding non numeric values, intreval field displays validation error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("test_name_two") + input_page.entity2.interval.set_value("abc") + self.assert_util( + input_page.entity2.save, + r"Interval must be an integer.", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_required_field_index( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field index in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_account.select("test_input") + input_page.entity2.example_radio.select("No") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.interval.set_value("90") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + input_page.entity2.index.cancel_selected_value() + self.assert_util( + input_page.entity2.save, + r"Field Index is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_default_value_index( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of field index in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + default_index = "default" + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + self.assert_util(input_page.entity2.index.get_value, default_index) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_required_field_example_example_account( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field Account in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_radio.select("No") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.index.select("main") + input_page.entity2.interval.set_value("90") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity2.save, + r"Field Example Account is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_required_field_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies required field Example Multiple Select in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_radio.select("No") + input_page.entity2.index.select("main") + input_page.entity2.interval.set_value("90") + input_page.entity2.example_account.select("test_input") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity2.save, + r"Field Example Multiple Select is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_list_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies values of Multiple Select Test dropdown in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + example_multiple_select_list = ["Option One", "Option Two"] + self.assert_util( + input_page.entity2.example_multiple_select.list_of_values(), + example_multiple_select_list, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_select_select_value_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies selected single value of Multiple Select Test dropdown in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_value = ["Option One"] + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.index.select("main") + for each in selected_value: + input_page.entity2.example_multiple_select.select(each) + self.assert_util( + input_page.entity2.example_multiple_select.get_values, selected_value + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_select_multiple_values_example_multiple_select( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies selected multiple values of Multiple Select Test dropdown in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + selected_values = ["Option One", "Option Two"] + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.index.select("main") + for each in selected_values: + input_page.entity2.example_multiple_select.select(each) + self.assert_util( + input_page.entity2.example_multiple_select.get_values, selected_values + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_help_text_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies help text for the field name""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + self.assert_util( + input_page.entity2.example_multiple_select.get_help_text, + "This is an example multipleSelect for input two entity", + ) + self.assert_util( + input_page.entity2.name.get_help_text, "A unique name for the data input." + ) + self.assert_util( + input_page.entity2.interval.get_help_text, + "Time interval of the data input, in seconds .", + ) + self.assert_util( + input_page.entity2.example_checkbox.get_help_text, + "This is an example checkbox for the input two entity", + ) + self.assert_util( + input_page.entity2.example_radio.get_help_text, + "This is an example radio button for the input two entity", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_checked_example_checkbox( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies Check in example checkbox in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + self.assert_util(input_page.entity2.example_checkbox.check, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_unchecked_example_checkbox( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies Uncheck in example checkbox in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.example_checkbox.check() + self.assert_util(input_page.entity2.example_checkbox.uncheck, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_required_field_example_radio( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of example radio in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.index.select("main") + input_page.entity2.interval.set_value("90") + input_page.entity2.example_account.select("test_input") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util( + input_page.entity2.save, + r"Field Example Radio is required", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_select_value_example_radio( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies default value of example radio in Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.example_radio.select("No") + self.assert_util(input_page.entity2.example_radio.get_value, "No") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_valid_input_query_start_date( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether adding wrong format, Query Start Date field displays validation error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("test_name_two") + input_page.entity2.interval.set_value("120") + input_page.entity2.example_account.select("test_input") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.example_radio.select("Yes") + input_page.entity2.query_start_date.set_value("2020/01/01") + self.assert_util( + input_page.entity2.save, + r"Invalid date and time format", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_add_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the frontend after adding a Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_radio.select("No") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.example_multiple_select.select("Option Two") + input_page.entity2.index.select("main") + input_page.entity2.interval.set_value("90") + input_page.entity2.example_account.select("test_input") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util(input_page.entity2.save, True) + input_page.table.wait_for_rows_to_appear(1) + self.assert_util( + input_page.table.get_table()["dummy_input"], + { + "name": "dummy_input", + "account": "test_input", + "interval": "90", + "index": "main", + "status": "Enabled", + "actions": "Edit | Clone | Delete", + }, + ) + url = input_page._get_input_endpoint() + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_add_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the backend after adding a Example Input Two""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input") + input_page.entity2.example_checkbox.check() + input_page.entity2.example_radio.select("No") + input_page.entity2.example_multiple_select.select("Option One") + input_page.entity2.example_multiple_select.select("Option Two") + input_page.entity2.index.select("main") + input_page.entity2.interval.set_value("90") + input_page.entity2.example_account.select("test_input") + input_page.entity2.query_start_date.set_value("2020-12-11T20:00:32.000z") + self.assert_util(input_page.entity2.save, True) + input_page.table.wait_for_rows_to_appear(1) + value_to_test = { + "account": "test_input", + "index": "main", + "input_two_checkbox": "1", + "input_two_radio": "0", + "interval": "90", + "input_two_multiple_select": "one,two", + "start_date": "2020-12-11T20:00:32.000z", + "disabled": 0, + } + backend_stanza = input_page.backend_conf.get_stanza( + "example_input_two://dummy_input" + ) + for each_key, each_value in value_to_test.items(): + self.assert_util(each_value, backend_stanza[each_key]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_edit_uneditable_field_name( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the frontend uneditable fields at time of edit of the Example Input Two entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + self.assert_util(input_page.entity2.name.is_editable, False) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_edit_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the frontend edit functionality of the Example Input Two entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.example_checkbox.uncheck() + input_page.entity2.example_radio.select("Yes") + input_page.entity2.example_account.select("test_input") + input_page.entity2.example_multiple_select.deselect("Option One") + input_page.entity2.interval.set_value("3600") + input_page.entity2.query_start_date.set_value("2020-20-20T20:20:20.000z") + self.assert_util(input_page.entity2.save, True) + input_page.table.wait_for_rows_to_appear(1) + self.assert_util( + input_page.table.get_table()["dummy_input_two"], + { + "name": "dummy_input_two", + "account": "test_input", + "interval": "3600", + "index": "main", + "status": "Enabled", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_edit_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the backend edit functionality of the Example Input Two entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.example_checkbox.uncheck() + input_page.entity2.example_account.select("test_input") + input_page.entity2.example_radio.select("Yes") + input_page.entity2.example_multiple_select.deselect("Option One") + input_page.entity2.interval.set_value("3600") + input_page.entity2.query_start_date.set_value("2020-20-20T20:20:20.000z") + self.assert_util(input_page.entity2.save, True) + input_page.table.wait_for_rows_to_appear(1) + value_to_test = { + "account": "test_input", + "input_two_checkbox": "0", + "input_two_radio": "1", + "interval": "3600", + "index": "main", + "input_two_multiple_select": "two", + "start_date": "2020-20-20T20:20:20.000z", + "disabled": 0, + } + backend_stanza = input_page.backend_conf.get_stanza( + "example_input_two://dummy_input_two" + ) + for each_key, each_value in value_to_test.items(): + self.assert_util(each_value, backend_stanza[each_key]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_clone_default_values( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the frontend default fields at time of clone for Example Input Two entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + self.assert_util(input_page.entity2.name.get_value, "") + self.assert_util(input_page.entity2.example_checkbox.is_checked, True) + self.assert_util(input_page.entity2.example_radio.get_value, "No") + self.assert_util( + input_page.entity2.example_multiple_select.get_values, + ["Option One", "Option Two"], + ) + self.assert_util(input_page.entity2.interval.get_value, "100") + self.assert_util(input_page.entity2.index.get_value, "main") + self.assert_util(input_page.entity2.example_account.get_value, "test_input") + self.assert_util( + input_page.entity2.query_start_date.get_value, "2016-10-10T12:10:15.000z" + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_clone_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the frontend clone functionality of the Example Input Two entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.wait_for_rows_to_appear(1) + input_page.table.clone_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("dummy_input_two_Clone_Test") + input_page.entity2.interval.set_value("180") + self.assert_util(input_page.entity2.save, True) + input_page.table.wait_for_rows_to_appear(2) + self.assert_util( + input_page.table.get_table()["dummy_input_two_Clone_Test"], + { + "name": "dummy_input_two_Clone_Test", + "account": "test_input", + "interval": "180", + "index": "main", + "status": "Enabled", + "actions": "Edit | Clone | Delete", + }, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_clone_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the backend clone functionality of the Example Input Two entity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.wait_for_rows_to_appear(1) + input_page.table.clone_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + input_page.entity2.name.set_value("Clone_Test") + input_page.entity2.interval.set_value("180") + self.assert_util(input_page.entity2.save, True) + input_page.table.wait_for_rows_to_appear(2) + value_to_test = { + "account": "test_input", + "input_two_checkbox": "1", + "input_two_radio": "0", + "interval": "180", + "index": "main", + "input_two_multiple_select": "one,two", + "start_date": "2016-10-10T12:10:15.000z", + "disabled": 0, + } + backend_stanza = input_page.backend_conf.get_stanza( + "example_input_two://Clone_Test" + ) + for each_key, each_value in value_to_test.items(): + self.assert_util(each_value, backend_stanza[each_key]) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_delete_row_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the frontend delete functionlity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.input_status_toggle("dummy_input_two", enable=False) + input_page.table.delete_row("dummy_input_two") + input_page.table.wait_for_rows_to_appear(0) + self.assert_util("dummy_input_two", input_page.table.get_table, "not in") + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + @pytest.mark.sanity_test + def test_example_input_two_delete_row_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the backend delete functionlity""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.input_status_toggle("dummy_input_two", enable=False) + input_page.table.delete_row("dummy_input_two") + input_page.table.wait_for_rows_to_appear(0) + self.assert_util( + "example_input_two://dummy_input_two", + input_page.backend_conf.get_all_stanzas().keys(), + "not in", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_add_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies close functionality at time of add""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + self.assert_util(input_page.entity2.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_edit_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies close functionality at time of edit""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_two") + self.assert_util(input_page.entity2.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_clone_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies close functionality at time of clone""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_two") + self.assert_util(input_page.entity2.close, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_delete_close_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies close functionality at time of delete""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.delete_row, + True, + left_args={"name": "dummy_input_two", "close": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_add_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies cancel functionality at time of add""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + self.assert_util(input_page.entity2.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_edit_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies cancel functionality at time of edit""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_two") + self.assert_util(input_page.entity2.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_clone_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies cancel functionality at time of clone""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_two") + self.assert_util(input_page.entity2.cancel, True) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_delete_cancel_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies cancel functionality at time of delete""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + self.assert_util( + input_page.table.delete_row, + True, + left_args={"name": "dummy_input_two", "cancel": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_add_duplicate_names( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies by saving an entity with duplicate name it displays and error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + input_name = "dummy_input_two" + input_page.entity2.name.set_value(input_name) + self.assert_util( + input_page.entity2.save, + "Name {} is already in use".format(input_name), + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_clone_duplicate_names( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies by saving an entity with duplicate name at time of clone it displays and error""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + input_name = "dummy_input_two" + input_page.entity2.name.set_value(input_name) + self.assert_util( + input_page.entity2.save, + "Name {} is already in use".format(input_name), + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_add_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the title of the 'Add Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.create_new_input.select("Example Input Two") + input_page.entity2.example_account.wait_for_values() + self.assert_util( + input_page.entity2.title.container.get_attribute("textContent").strip(), + "Add Example Input Two", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_edit_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the title of the 'Edit Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.edit_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + self.assert_util( + input_page.entity2.title.container.get_attribute("textContent").strip(), + "Update Example Input Two", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_clone_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the title of the 'Clone Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.clone_row("dummy_input_two") + input_page.entity2.example_account.wait_for_values() + self.assert_util( + input_page.entity2.title.container.get_attribute("textContent").strip(), + "Clone Example Input Two", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_delete_valid_title( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the title of the 'Delete Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_page.table.delete_row("dummy_input_two", prompt_msg=True) + self.assert_util( + input_page.entity2.title.container.get_attribute("textContent").strip(), + "Delete Confirmation", + ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.input + def test_example_input_two_delete_valid_prompt_message( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_two + ): + """Verifies the prompt message of the 'Delete Entity'""" + input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) + input_name = "dummy_input_two" + prompt_message = input_page.table.delete_row("dummy_input_two", prompt_msg=True) + self.assert_util( + prompt_message, 'Are you sure you want to delete "{}" ?'.format(input_name) + ) diff --git a/tests/ui/test_splunk_ta_example_addon_logging.py b/tests/ui/test_splunk_ta_example_addon_logging.py new file mode 100644 index 00000000..2f88425e --- /dev/null +++ b/tests/ui/test_splunk_ta_example_addon_logging.py @@ -0,0 +1,34 @@ +from pytest_splunk_addon_ui_smartx.base_test import UccTester +from pytest_splunk_addon_ui_smartx.pages.logging import Logging +import pytest +import random + +TA_NAME = "Splunk_TA_UCCExample" +TA_CONF = "splunk_ta_uccexample_settings" + +DEFAULT_CONFIGURATION = {"loglevel": "INFO"} + + +@pytest.fixture(autouse=True) +def reset_configuration(ucc_smartx_rest_helper): + yield + logging = Logging(TA_NAME, TA_CONF, ucc_smartx_rest_helper=ucc_smartx_rest_helper) + logging.backend_conf.update_parameters(DEFAULT_CONFIGURATION) + + +class TestLogging(UccTester): + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.logging + def test_logging_select_random_log_level( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test cases checks the functionality of selecting random log level and verification of the same in UI""" + levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] + logging = Logging( + TA_NAME, TA_CONF, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ) + level = random.choice(levels) + logging.log_level.select(level) + logging.save() + self.assert_util(logging.log_level.get_value().lower(), level.lower()) diff --git a/tests/ui/test_splunk_ta_example_addon_proxy.py b/tests/ui/test_splunk_ta_example_addon_proxy.py new file mode 100644 index 00000000..fea0e03d --- /dev/null +++ b/tests/ui/test_splunk_ta_example_addon_proxy.py @@ -0,0 +1,374 @@ +from pytest_splunk_addon_ui_smartx.base_test import UccTester +from pytest_splunk_addon_ui_smartx.pages.proxy import Proxy +import pytest + +TA_NAME = "Splunk_TA_UCCExample" +TA_CONF = "splunk_ta_uccexample_settings" +TA_PROXY_URL = ( + "/servicesNS/nobody/Splunk_TA_UCCExample/splunk_ta_uccexample_settings/proxy" +) + +DEFAULT_CONFIGURATION = { + "proxy_enabled": 0, + "proxy_password": "", + "proxy_port": "", + "proxy_rdns": 0, + "proxy_type": "http", + "proxy_url": "", + "proxy_username": "", +} + + +@pytest.fixture(autouse=True) +def reset_configuration(ucc_smartx_rest_helper): + yield + proxy = Proxy( + TA_NAME, TA_PROXY_URL, TA_CONF, ucc_smartx_rest_helper=ucc_smartx_rest_helper + ) + proxy.backend_conf_post.update_parameters(DEFAULT_CONFIGURATION) + + +class TestProxy(UccTester): + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_fields_label_entity( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies proxy field label""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + self.assert_util(proxy.proxy_enable.get_input_label, "Enable") + self.assert_util(proxy.type.get_input_label, "Proxy Type") + self.assert_util(proxy.host.get_input_label, "Host") + self.assert_util(proxy.port.get_input_label, "Port") + self.assert_util(proxy.username.get_input_label, "Username") + self.assert_util(proxy.password.get_input_label, "Password") + self.assert_util(proxy.dns_enable.get_input_label, "Reverse DNS resolution") + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_fields_placeholder_value( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies proxy input field placeholder value""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + self.assert_util(proxy.host.get_placeholder_value, "optional") + self.assert_util(proxy.port.get_placeholder_value, "optional") + self.assert_util(proxy.username.get_placeholder_value, "optional") + self.assert_util(proxy.password.get_placeholder_value, "optional") + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_default_configs( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the default proxy configurations""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + self.assert_util(proxy.proxy_enable.is_checked, False) + self.assert_util(proxy.dns_enable.is_checked, False) + self.assert_util(proxy.type.get_value, "http") + self.assert_util(proxy.host.get_value, "") + self.assert_util(proxy.port.get_value, "") + self.assert_util(proxy.username.get_value, "") + self.assert_util(proxy.password.get_value, "") + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_required_field_host( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether the host field in proxy is required and displays an error if left empty""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.proxy_enable.check() + proxy.type.cancel_selected_value() + proxy.type.select("http") + proxy.dns_enable.check() + proxy.port.set_value("3285") + proxy.username.set_value("Username") + proxy.password.set_value("Password") + self.assert_util( + proxy.save, "Proxy Host can not be empty", left_args={"expect_error": True} + ) + proxy.dns_enable.check() + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_host_valid_input( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies if host contains special characters displays an error""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.host.set_value("abc$$") + self.assert_util( + proxy.save, + "Proxy Host should not have special characters", + left_args={"expect_error": True}, + ) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_host_field_length_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies host field length validation""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + host_value = "a" * 4097 + proxy.host.set_value(host_value) + self.assert_util( + proxy.save, "Max host length is 4096", left_args={"expect_error": True} + ) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_required_field_port( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether the proxy field is required and displays an error if left empty""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.proxy_enable.check() + proxy.type.cancel_selected_value() + proxy.type.select("http") + proxy.dns_enable.check() + proxy.host.set_value("host") + proxy.username.set_value("Username") + proxy.password.set_value("Password") + self.assert_util( + proxy.save, "Proxy Port can not be empty", left_args={"expect_error": True} + ) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_port_field_valid_range( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether the proxy field only allows numeric values""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.host.set_value("abc") + proxy.port.set_value("abc") + self.assert_util( + proxy.save, "Field Port is not a number", left_args={"expect_error": True} + ) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_port_field_out_of_range( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """verifies out of range port value""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.host.set_value("abc") + proxy.port.set_value("65536") + self.assert_util( + proxy.save, + "Field Port should be within the range of [1 and 65535]", + left_args={"expect_error": True}, + ) + proxy.port.set_value("") + self.assert_util(proxy.is_error_closed, True) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_list_proxy_types( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """This test case checks list of proxy types present in the drop down""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + self.assert_util(proxy.type.list_of_values(), ["http", "socks4", "socks5"]) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_required_field_proxy_type( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies whether proxy type is required and displays an error if left empty""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.proxy_enable.check() + proxy.type.cancel_selected_value() + proxy.type.select("http") + proxy.dns_enable.check() + proxy.host.set_value("host") + proxy.port.set_value("3285") + proxy.username.set_value("Username") + proxy.password.set_value("Password") + proxy.type.cancel_selected_value() + self.assert_util( + proxy.save, "Proxy type can not be empty", left_args={"expect_error": True} + ) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_username_field_length_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies username field length validation""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + username_value = "a" * 51 + proxy.host.set_value("abc") + proxy.port.set_value("65535") + proxy.username.set_value(username_value) + self.assert_util( + proxy.save, "Max length of username is 50", left_args={"expect_error": True} + ) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + def test_proxy_encrypted_field_password( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies if the password field is masked or not in the Textbox""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + textbox_type = proxy.password.get_type() + self.assert_util(textbox_type, "password") + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + @pytest.mark.sanity_test + def test_proxy_frontend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the proxy is saved properly in frontend after saving it""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.proxy_enable.check() + proxy.type.cancel_selected_value() + proxy.type.select("http") + proxy.dns_enable.check() + proxy.host.set_value("host") + proxy.port.set_value("3285") + proxy.username.set_value("Username") + proxy.password.set_value("Password") + self.assert_util(proxy.save, True) + + @pytest.mark.execute_enterprise_cloud_false + @pytest.mark.forwarder + @pytest.mark.proxy + @pytest.mark.sanity_test + def test_proxy_backend_validation( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the proxy is saved properly in frontend after saving it""" + proxy = Proxy( + TA_NAME, + TA_PROXY_URL, + TA_CONF, + ucc_smartx_selenium_helper, + ucc_smartx_rest_helper, + ) + proxy.proxy_enable.check() + proxy.type.cancel_selected_value() + proxy.type.select("http") + proxy.dns_enable.check() + proxy.host.set_value("host") + proxy.port.set_value("3285") + proxy.username.set_value("Username") + proxy.password.set_value("Password") + proxy.save() + self.assert_util( + proxy.backend_conf_get.get_stanza(decrypt=True), + { + "disabled": False, + "proxy_enabled": "1", + "proxy_port": "3285", + "proxy_rdns": "1", + "proxy_type": "http", + "proxy_url": "host", + "proxy_password": "Password", + "proxy_username": "Username", + }, + ) diff --git a/tests/unit/pytest.ini b/tests/unit/pytest.ini index e75de70a..309368c1 100644 --- a/tests/unit/pytest.ini +++ b/tests/unit/pytest.ini @@ -1,5 +1,4 @@ [pytest] addopts = -v --tb=long --log-level=INFO -# --force-flaky --max-runs=3 --min-passes=1 filterwarnings = ignore::DeprecationWarning From cdc142ff85dc77d33c0de05567546df1586b05aa Mon Sep 17 00:00:00 2001 From: Artem Rys Date: Thu, 14 Sep 2023 15:04:06 +0200 Subject: [PATCH 2/5] test(ui): fix issue with alert actions --- .../ui/test_splunk_ta_example_addon_alert_actions.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/ui/test_splunk_ta_example_addon_alert_actions.py b/tests/ui/test_splunk_ta_example_addon_alert_actions.py index 3c087be0..319f3c69 100644 --- a/tests/ui/test_splunk_ta_example_addon_alert_actions.py +++ b/tests/ui/test_splunk_ta_example_addon_alert_actions.py @@ -16,6 +16,7 @@ def setup_alert(ucc_smartx_selenium_helper): # Splunk 8.x if not setup_alert.first_execution: return + AlertPage(ucc_smartx_selenium_helper, None, open_page=False) intro_popup = Button( ucc_smartx_selenium_helper.browser, @@ -25,6 +26,14 @@ def setup_alert(ucc_smartx_selenium_helper): intro_popup.click() setup_alert.first_execution = False + # Splunk 8.2.x + intro_popup = Button( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="label"]'), + ) + intro_popup.wait_to_be_clickable() + intro_popup.click() + # Splunk 8.0.x important_changes_coming = Button( ucc_smartx_selenium_helper.browser, @@ -34,7 +43,7 @@ def setup_alert(ucc_smartx_selenium_helper): ) important_changes_coming.wait_to_be_clickable() important_changes_coming.click() - except: + except Exception: pass From 89d1f31d64af92ca8d1d69bddcd697949e59adf8 Mon Sep 17 00:00:00 2001 From: Artem Rys Date: Thu, 14 Sep 2023 15:05:35 +0200 Subject: [PATCH 3/5] fix(toggle): update queries to control Toggle --- pytest_splunk_addon_ui_smartx/components/controls/toggle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pytest_splunk_addon_ui_smartx/components/controls/toggle.py b/pytest_splunk_addon_ui_smartx/components/controls/toggle.py index dfb6e3bb..2c212f98 100644 --- a/pytest_splunk_addon_ui_smartx/components/controls/toggle.py +++ b/pytest_splunk_addon_ui_smartx/components/controls/toggle.py @@ -36,11 +36,11 @@ def __init__(self, browser, container): { "toggle_btn": Selector( select=container.select - + ' [data-test="option"] [data-test="label"]' + + ' [data-test="option"] :not([data-test=’screen-reader-content’])' ), "selected": Selector( select=container.select - + ' [data-test="option"][aria-checked="true"] [data-test="label"]' + + ' [data-test="option"][aria-checked="true"] :not([data-test=’screen-reader-content’])' ), } ) From ea6699fbc28e9e53c8cfc9036e1faa24fa2ffcbc Mon Sep 17 00:00:00 2001 From: Artem Rys Date: Thu, 14 Sep 2023 15:24:22 +0200 Subject: [PATCH 4/5] ci: build add-on once --- .github/workflows/build-test-release.yaml | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-test-release.yaml b/.github/workflows/build-test-release.yaml index dfc09efc..493cbb18 100644 --- a/.github/workflows/build-test-release.yaml +++ b/.github/workflows/build-test-release.yaml @@ -101,11 +101,20 @@ jobs: - run: | poetry install poetry build + - run: | + poetry run ucc-gen build \ + --source=tests/testdata/Splunk_TA_UCCExample/package \ + --config=tests/testdata/Splunk_TA_UCCExample/globalConfig.json \ + --ta-version=0.0.1 - uses: actions/upload-artifact@v3 with: name: package path: dist/* if: always() + - uses: actions/upload-artifact@v3 + with: + name: output + path: output/* run-ui-tests: needs: @@ -137,20 +146,13 @@ jobs: with: name: package path: dist/ + - uses: actions/download-artifact@v3 + with: + name: output + path: output/ - run: | git submodule sync git submodule update --recursive --remote - - uses: actions/setup-python@v4 - with: - python-version: 3.7 - - run: curl -sSL https://install.python-poetry.org | python3 - --version 1.4.2 - - name: Setup for testing - run: | - poetry install - poetry run ucc-gen build \ - --source=tests/testdata/Splunk_TA_UCCExample/package \ - --config=tests/testdata/Splunk_TA_UCCExample/globalConfig.json \ - --ta-version=0.0.1 - name: Splunk Testing run: | mkdir test-results From 40b64377233b1d4796d7bd262d2e593f701dc7d5 Mon Sep 17 00:00:00 2001 From: Artem Rys Date: Thu, 14 Sep 2023 16:48:30 +0200 Subject: [PATCH 5/5] test: remove pytest expect --- Dockerfile-tests | 3 --- tests/ui/.pytest.expect | 7 ------- tests/ui/test_splunk_ta_example_addon_account.py | 4 ++++ tests/ui/test_splunk_ta_example_addon_custom.py | 1 + tests/ui/test_splunk_ta_example_addon_input.py | 14 -------------- 5 files changed, 5 insertions(+), 24 deletions(-) delete mode 100644 tests/ui/.pytest.expect diff --git a/Dockerfile-tests b/Dockerfile-tests index 8939f105..5630c6a9 100644 --- a/Dockerfile-tests +++ b/Dockerfile-tests @@ -30,12 +30,9 @@ ENV LANG en_US.utf8 COPY dist /work/dist COPY tests/ui/pytest-ci.ini /work/pytest.ini RUN pip install /work/dist/*.whl -RUN pip install pytest-splunk-addon -RUN pip install pytest-expect RUN pip install pytest-rerunfailures COPY tests/entrypoint.sh / COPY tests /work/tests -COPY tests/ui/.pytest.expect /work/.pytest.expect RUN cd /work/tests && ls RUN cd ../.. diff --git a/tests/ui/.pytest.expect b/tests/ui/.pytest.expect deleted file mode 100644 index 2347e147..00000000 --- a/tests/ui/.pytest.expect +++ /dev/null @@ -1,7 +0,0 @@ -pytest-expect file v1 -(3, 7, 7, 'final', 0) -u'tests/knowledge/test_addon.py::Test_App::test_tags[eventtype="UCC_NOT_GENERATED"::tag::notalert]': FAIL -u'tests/knowledge/test_addon.py::Test_App::test_eventtype[eventtype::UCC_NOT_GENERATED]': FAIL -u'tests/ui/test_splunk_ta_example_addon_account.py::TestAccount::test_account_basic_fields_label_entity': FAIL -u'tests/ui/test_splunk_ta_example_addon_account.py::TestAccount::test_account_oauth_fields_label_entity': FAIL -u'tests/ui/test_splunk_ta_example_addon_input.py::TestInput::test_inputs_delete_enabled_input': FAIL diff --git a/tests/ui/test_splunk_ta_example_addon_account.py b/tests/ui/test_splunk_ta_example_addon_account.py index 050ff97c..29f57cad 100644 --- a/tests/ui/test_splunk_ta_example_addon_account.py +++ b/tests/ui/test_splunk_ta_example_addon_account.py @@ -532,6 +532,10 @@ def test_account_help_text_entity( @pytest.mark.execute_enterprise_cloud_true @pytest.mark.forwarder @pytest.mark.account + @pytest.mark.xfail( + reason="account.entity.environment.cancel_selected_value() is flaky, " + "passing locally, not working in CI, will be investigated later." + ) def test_account_required_field_example_environment( self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper ): diff --git a/tests/ui/test_splunk_ta_example_addon_custom.py b/tests/ui/test_splunk_ta_example_addon_custom.py index 3c45e3de..9c03aadc 100644 --- a/tests/ui/test_splunk_ta_example_addon_custom.py +++ b/tests/ui/test_splunk_ta_example_addon_custom.py @@ -102,6 +102,7 @@ def test_custom_backend_validation( custom.backend_conf.get_stanza, { "disabled": False, + "test_help_link": "", "test_number": "7", "test_regex": "test_rex", "test_string": "test_str", diff --git a/tests/ui/test_splunk_ta_example_addon_input.py b/tests/ui/test_splunk_ta_example_addon_input.py index 55e1a6ee..c981786b 100644 --- a/tests/ui/test_splunk_ta_example_addon_input.py +++ b/tests/ui/test_splunk_ta_example_addon_input.py @@ -275,20 +275,6 @@ def test_inputs_input_type_list_values( input_page.type_filter.select_input_type("Example Input Two") self.assert_util(input_page.table.get_row_count, 1) - @pytest.mark.execute_enterprise_cloud_true - @pytest.mark.forwarder - @pytest.mark.input - def test_inputs_delete_enabled_input( - self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper, add_input_one - ): - """Verifies enabled input should not delete""" - input_page = InputPage(ucc_smartx_selenium_helper, ucc_smartx_rest_helper) - self.assert_util( - input_page.table.delete_row, - r"Can't delete enabled input", - left_args={"name": "dummy_input_one"}, - ) - @pytest.mark.execute_enterprise_cloud_true @pytest.mark.forwarder @pytest.mark.input