├── .gitignore ├── Components ├── BasicComponent.py ├── Common │ ├── Button.py │ ├── FileUpload.py │ └── TextInput.py └── PerspectiveComponents │ ├── Charts │ ├── Pie.py │ ├── PowerChart.py │ ├── TimeSeriesChart.py │ └── XYChart.py │ ├── Common │ ├── Checkbox.py │ ├── ComponentModal.py │ ├── DateRangeSelector.py │ ├── DateTimePicker.py │ ├── Dropdown.py │ ├── Icon.py │ ├── Table.py │ ├── TablePieces │ │ ├── Body.py │ │ ├── Filter.py │ │ ├── HeaderAndFooter.py │ │ └── Pager.py │ ├── TagBrowseTree.py │ └── Tree.py │ ├── Containers │ ├── Column.py │ ├── Coordinate.py │ ├── Split.py │ └── Tab.py │ ├── Displays │ ├── AlarmTable.py │ ├── Audio.py │ ├── Barcode.py │ ├── CylindricalTank.py │ ├── Dashboard.py │ ├── EquipmentSchedule.py │ ├── GoogleMap.py │ ├── Icon.py │ ├── Image.py │ ├── InlineFrame.py │ ├── LEDDisplay.py │ ├── Label.py │ ├── LinearScale.py │ ├── Map.py │ ├── Markdown.py │ ├── Progress.py │ ├── Table.py │ ├── TagBrowseTree.py │ ├── Thermometer.py │ ├── Tree.py │ └── VideoPlayer.py │ ├── Embedding │ ├── Accordion.py │ ├── Carousel.py │ ├── EmbeddedView.py │ ├── FlexRepeater.py │ └── ViewCanvas.py │ ├── Inputs │ ├── BarcodeScanner.py │ ├── Button.py │ ├── Checkbox.py │ ├── DateTime.py │ ├── Dropdown.py │ ├── FileUpload.py │ ├── MultiStateButton.py │ ├── NumericEntryField.py │ ├── OneShotButton.py │ ├── PasswordField.py │ ├── RadioGroup.py │ ├── SignaturePad.py │ ├── Slider.py │ ├── TextArea.py │ ├── TextField.py │ └── ToggleSwitch.py │ ├── Navigation │ ├── HorizontalMenu.py │ ├── Link.py │ └── MenuTree.py │ ├── Reporting │ └── ReportViewer.py │ ├── Symbols │ └── Symbol.py │ └── Tooltip.py ├── Helpers ├── CSSEnumerations.py ├── Filtering.py ├── Formatting.py ├── GeographicPoint.py ├── IAAssert.py ├── IAExpectedConditions │ └── IAExpectedConditions.py ├── IASelenium.py ├── Ignition │ ├── Alarm.py │ ├── AlarmEvent.py │ ├── QualifiedValue.py │ └── Tag.py ├── PerspectiveAlarm.py ├── PerspectivePages │ ├── AuthChallengeHelper.py │ ├── DockedViewHelper.py │ ├── LoginHelper.py │ ├── NotificationHelper.py │ ├── PopupHelper.py │ ├── Quality.py │ └── QualityOverlayHelper.py └── Point.py ├── LICENSE ├── Pages ├── BasicPageObject.py ├── IgnitionPageObject.py ├── PagePiece.py ├── Perspective │ ├── AppBar.py │ ├── DockedView.py │ ├── Popup.py │ ├── PrintPreviewPage.py │ ├── TerminalStates │ │ ├── Forbidden.py │ │ ├── LoggedOut.py │ │ ├── MobileLicense.py │ │ ├── PageClosed.py │ │ ├── ProjectNotFound.py │ │ ├── ProjectNotRunnable.py │ │ ├── SessionClosed.py │ │ └── TerminalStatePageObject.py │ ├── View.py │ ├── ViewCanvasInstancedView.py │ └── Widget.py └── PerspectivePageObject.py ├── README.md └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Pycharm files 2 | .idea/ 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | .hypothesis/ 50 | .pytest_cache/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | db.sqlite3 60 | 61 | # Flask stuff: 62 | instance/ 63 | .webassets-cache 64 | 65 | # Scrapy stuff: 66 | .scrapy 67 | 68 | # Sphinx documentation 69 | docs/_build/ 70 | 71 | # PyBuilder 72 | target/ 73 | 74 | # Jupyter Notebook 75 | .ipynb_checkpoints 76 | 77 | # pyenv 78 | .python-version 79 | 80 | # celery beat schedule file 81 | celerybeat-schedule 82 | 83 | # SageMath parsed files 84 | *.sage.py 85 | 86 | # Environments 87 | .env 88 | .venv 89 | env/ 90 | venv/ 91 | ENV/ 92 | env.bak/ 93 | venv.bak/ 94 | 95 | # Spyder project settings 96 | .spyderproject 97 | .spyproject 98 | 99 | # Rope project settings 100 | .ropeproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | -------------------------------------------------------------------------------- /Components/Common/Button.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple, List, Optional, Union 2 | 3 | from selenium.common.exceptions import TimeoutException 4 | from selenium.webdriver.common.by import By 5 | from selenium.webdriver.remote.webdriver import WebDriver 6 | 7 | from Components.BasicComponent import ComponentPiece 8 | from Components.PerspectiveComponents.Common.Icon import CommonIcon 9 | from Helpers.CSSEnumerations import CSSPropertyValue 10 | from Helpers.Point import Point 11 | 12 | 13 | class CommonButton(ComponentPiece): 14 | """ 15 | A common button, exposing common functions which EVERY button in Perspective can use. This includes buttons within 16 | other components, like the Acknowledge button found inside the Alarm Status Table component. 17 | """ 18 | _INTERNAL_BUTTON_LOCATOR = (By.CSS_SELECTOR, 'button') 19 | _INTERNAL_ICON_LOCATOR = (By.TAG_NAME, "svg") 20 | _INTERNAL_TEXT_LOCATOR = (By.CSS_SELECTOR, "div.text") 21 | _INTERNAL_IMAGE_LOCATOR = (By.TAG_NAME, "img") 22 | PRIMARY_CLASS = 'ia_button--primary' 23 | SECONDARY_CLASS = 'ia_button--secondary' 24 | 25 | def __init__( 26 | self, 27 | locator: Tuple[By, str], 28 | driver: WebDriver, 29 | parent_locator_list: Optional[List[Tuple[By, str]]] = None, 30 | wait_timeout: float = 10, 31 | description: Optional[str] = None, 32 | poll_freq: float = 0.5): 33 | super().__init__( 34 | locator=locator, 35 | driver=driver, 36 | parent_locator_list=parent_locator_list, 37 | wait_timeout=wait_timeout, 38 | description=description, 39 | poll_freq=poll_freq) 40 | self._internal_button = ComponentPiece( 41 | locator=self._INTERNAL_BUTTON_LOCATOR, 42 | driver=self.driver, 43 | parent_locator_list=self.locator_list, 44 | description="The internal HTML