Source code for pytest_splunk_addon_ui_smartx.components.controls.multi_select

#
# Copyright 2023 Splunk Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import time

from selenium.common.exceptions import ElementClickInterceptedException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

from ..base_component import Selector
from .base_control import BaseControl


[docs]class MultiSelect(BaseControl): """ Entity-Component: Multiselect Select Javascript framework: select2 A dropdown which can select more than one values """ def __init__(self, browser, container): """ :param browser: The selenium webdriver :param container: The locator of the container where the control is located in """ super().__init__(browser, container) self.elements.update( { "internal_container": Selector( select=container.select + ' [role="listbox"]' ), "dropdown": Selector(select=container.select + ' [role="listbox"]'), "selected": Selector( select=container.select + ' button[data-test="selected-option"][role="option"]' ), "deselect": Selector( select=container.select + ' [data-test="crossmark"]' ), "input": Selector(select=container.select + ' [data-test="textbox"]'), } )
[docs] def search(self, value): """ search with the multiselect input :param value: string value to search """ self.input.send_keys(value)
[docs] def clear_text(self): """ Clears the search box value in the multiselect field """ self.input.clear()
[docs] def search_get_list(self, value): """ search with the multiselect input and return the list :param value: string value to search :returns: list of values """ self.search(value) self.wait_for_search_list() searched_values = list(self._list_visible_values()) self.input.send_keys(Keys.ESCAPE) self.wait_for("container") return searched_values
[docs] def select(self, value): """ select a single value :param value: the value to select :return: Bool returns true if selection was successful, else raises an exception """ try: time.sleep(1) try: self.input.click() except ElementClickInterceptedException: self.label_text.click() time.sleep(1) self.input.click() time.sleep(1) popoverid = "#" + self.dropdown.get_attribute("data-test-popover-id") except: raise Exception("dropdown not found") self.elements.update( {"values": Selector(select=popoverid + ' [data-test="option"]')} ) for each in self.get_elements("values"): if each.text.strip().lower() == value.lower(): each.click() self.wait_for("input") return True else: raise ValueError("{} not found in select list".format(value))
[docs] def deselect(self, value): """ Remove an item from selected list. :param value: the value to deselect :return: Bool returns true if deselect was successful, else raises an exception """ for each in self.get_child_elements("selected"): if each.text.strip().lower() == value.lower(): time.sleep(1) each.find_element( *list(self.elements["deselect"]._asdict().values()) ).click() self.wait_for("internal_container") return True else: raise ValueError("{} not found in select list".format(value))
[docs] def deselect_all(self): """ Remove all items from selected list. """ for each in self.get_values(): self.deselect(each)
[docs] def get_values(self): """ get list selected values :returns: List of values selected within the multi-select """ return [each.text.strip() for each in self.get_child_elements("selected")]
[docs] def list_of_values(self): """ Get list of possible values to select from dropdown :returns: List of options within the multi-select dropdown """ self.wait_for("internal_container") time.sleep(1) list_of_values = [] self.input.click() popoverid = "#" + self.dropdown.get_attribute("data-test-popover-id") self.elements.update( { "values": Selector( select=popoverid + ' [data-test="option"] [data-test="label"]' ) } ) for each in self.get_elements("values"): list_of_values.append(each.text.strip()) return list_of_values
[docs] def get_list_count(self): """ Gets the total count of the Multiselect list """ return len(list(self.list_of_values()))
def _list_visible_values(self): """ Get list of values which are visible. Used while filtering :returns: List of visible options within the multi-select dropdown """ self.input.click() popoverid = "#" + self.dropdown.get_attribute("data-test-popover-id") self.elements.update( { "values": Selector( select=popoverid + ' [data-test="option"]:not([data-test-selected="true"]) [data-test="label"]' ) } ) for each in self.get_elements("values"): yield each.get_attribute("textContent")
[docs] def wait_for_values(self): """ Wait for dynamic values to load in Mulitple select """ def _wait_for_values(driver): return self.get_list_count() > 0 self.wait_for(_wait_for_values, msg="No values found in Multiselect")
[docs] def wait_for_search_list(self): """ Wait for Multiselect search to populate """ def _wait_for_search_list(driver): return len(list(self._list_visible_values())) > 0 self.wait_for( _wait_for_search_list, msg="No values found in Multiselect search" )