From 972641f4e0a3cb33e1ad80fffd0178fb1a7f10e5 Mon Sep 17 00:00:00 2001 From: vklonin Date: Mon, 11 Mar 2024 18:03:44 +0300 Subject: [PATCH 01/29] bumped dependencies and changed test site --- CONTRIBUTING.md | 6 +-- JDI/core/settings/jdi_settings.py | 13 +++--- .../driver/selenium_driver_factory.py | 46 ++++++------------- .../selenium/driver/web_driver_provider.py | 10 ++-- .../selenium/elements/common/text_field.py | 2 +- README.md | 14 ++++++ jdi.properties | 2 +- requirements.txt | 7 +-- .../main/entities/user.py | 7 +-- .../main/enums/preconditions.py | 14 +++--- .../main/page_objects/epam_jdi_site.py | 16 ++++--- .../main/page_objects/pages/login.py | 4 +- 12 files changed, 66 insertions(+), 75 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b67bd8f..8adabf7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Getting started Before you begin: -- Python 3.8 is used for this project. +- Python 3.11 is used for this project. - For EPAM employees only: have you read the [Best Practices for Managing Secrets](https://elearn.epam.com/courses/course-v1:EPAM+5SCSS+0620/courseware/4b94c749c309409ea878fb7916be316b/ae4553f7cd524229b42f260b0ac692ed/1?activate_block_id=block-v1%3AEPAM%2B5SCSS%2B0620%2Btype%40vertical%2Bblock%40c04f1498c7d04ac4bf87b652741d90bb)? - Check out the [existing issues](https://github.com/jdi-testing/jdi-python/issues). @@ -19,10 +19,6 @@ When you're done making changes, open your PR and get it reviewed. In order to test the project, run pytest. -Please don't forget to set up the environment variable `TEST_PASSWORD`. For example: - -For Windows `set TEST_PASSWORD=` - ```bash pytest /tests --no-header --no-summary -q ``` diff --git a/JDI/core/settings/jdi_settings.py b/JDI/core/settings/jdi_settings.py index 9f6b391..ef058dc 100644 --- a/JDI/core/settings/jdi_settings.py +++ b/JDI/core/settings/jdi_settings.py @@ -1,19 +1,20 @@ +import os +from pathlib import Path, PurePath import logging -from pathlib import Path - -logger = logging.Logger(__name__) +logger = logging.getLogger(__name__) class PropertyPath: def __init__(self, filename="jdi.properties"): - self._filename = Path(filename) + project_root = Path(__file__).parents[3] + self._filename = project_root / filename def get_property_file(self): - logger.info("Directory to search {dir_to_search}".format(dir_to_search=self._filename)) + logger.info(f"Directory to search {self._filename.parent}") if self._filename.exists(): return self._filename else: - raise FileNotFoundError("There is not property file with name '" + self._filename + "' in your project") + raise FileNotFoundError(f"There is no property file with name '{self._filename}' in your project") class JDISettings: diff --git a/JDI/web/selenium/driver/selenium_driver_factory.py b/JDI/web/selenium/driver/selenium_driver_factory.py index b6c89d7..a8303a7 100644 --- a/JDI/web/selenium/driver/selenium_driver_factory.py +++ b/JDI/web/selenium/driver/selenium_driver_factory.py @@ -1,14 +1,12 @@ -import os - +from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options as ChromeOptions from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver +from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.desired_capabilities import DesiredCapabilities -from selenium.webdriver.firefox.options import Options as FirefoxOptions from selenium.webdriver.remote.webdriver import WebDriver as RemoteDriver from JDI.core.settings.jdi_settings import JDISettings from JDI.web.selenium.driver.driver_types import DriverTypes -from JDI.web.selenium.driver.web_driver_provider import WebDriverProvider class SeleniumDriverFactory: @@ -17,7 +15,6 @@ def __init__(self): self.options = None self.current_driver = None self.browser_size = None - self.drivers_path = JDISettings.get_driver_path() self.capabilities = {} def register_driver(self, driver_name, options, capabilities, executor): @@ -28,24 +25,17 @@ def register_driver(self, driver_name, options, capabilities, executor): else: if driver_name == DriverTypes.chrome.name: self.current_driver = self.register_chrome_driver() - if driver_name == DriverTypes.firefox.name: - self.current_driver = self.register_firefox_driver() return driver_name def set_driver_options_and_capabilities(self, driver_name, options, capabilities, executor): if driver_name == DriverTypes.chrome.name: self.options = ChromeOptions() - # TODO: move hardcoded arguments to params self.options.add_argument("start-maximized") self.options.add_argument("disable-gpu") - self.add_options(options) if options else True - if not capabilities and executor is not None: + if options: + self.add_options(options) + if not capabilities and executor is None: self.capabilities = DesiredCapabilities.CHROME - if driver_name == DriverTypes.firefox.name: - self.options = FirefoxOptions() - self.add_options(options) if options else True - if not capabilities and executor is not None: - self.capabilities = DesiredCapabilities.FIREFOX if capabilities: self.capabilities = capabilities @@ -54,38 +44,28 @@ def add_options(self, options): self.options.add_argument(arg) def register_chrome_driver(self): - chrome_driver = WebDriverProvider.get_chrome_driver_path() - os.environ["webdriver.chrome.driver"] = chrome_driver - return self.__web_driver_settings(ChromeDriver(executable_path=chrome_driver, - options=self.options, - desired_capabilities=self.capabilities)) - - def register_firefox_driver(self): - raise NotImplementedError + service = Service(ChromeDriverManager().install()) + return self.__web_driver_settings(ChromeDriver(service=service, + options=self.options)) def register_remote_driver(self, executor): - chrome_driver = WebDriverProvider.get_chrome_driver_path() - os.environ["webdriver.chrome.driver"] = chrome_driver driver = self.__web_driver_settings(RemoteDriver(command_executor=executor, options=self.options, - desired_capabilities=self.capabilities, keep_alive=True)) return driver def __web_driver_settings(self, driver): - if self.browser_size is None: - driver.maximize_window() + if self.browser_size: + driver.set_window_size(*self.browser_size) else: - driver.set_window_size(self.browser_size) + driver.maximize_window() driver.implicitly_wait(JDISettings.get_current_timeout_sec()) return driver def get_driver(self, options=None, capabilities=None, executor=None): - if self.current_driver is not None: - return self.current_driver - else: + if not self.current_driver: self.register_driver(driver_name=DriverTypes.chrome.name, options=options, capabilities=capabilities, executor=executor) - return self.current_driver + return self.current_driver diff --git a/JDI/web/selenium/driver/web_driver_provider.py b/JDI/web/selenium/driver/web_driver_provider.py index e88acc5..af7a374 100644 --- a/JDI/web/selenium/driver/web_driver_provider.py +++ b/JDI/web/selenium/driver/web_driver_provider.py @@ -1,11 +1,9 @@ -import os +from webdriver_manager.chrome import ChromeDriverManager import sys -from JDI.core.settings.jdi_settings import JDISettings - - class WebDriverProvider: @staticmethod def get_chrome_driver_path(): - chrome = "/chromedriver.exe" if sys.platform.startswith("win") else "chromedriver" - return os.path.join(JDISettings.get_driver_path(), chrome) + chrome = ChromeDriverManager().install() + return chrome + diff --git a/JDI/web/selenium/elements/common/text_field.py b/JDI/web/selenium/elements/common/text_field.py index f6f3440..299d519 100644 --- a/JDI/web/selenium/elements/common/text_field.py +++ b/JDI/web/selenium/elements/common/text_field.py @@ -11,7 +11,7 @@ def __init__(self, by_locator=None, by_label=None, web_element=None): def input(self, text): self.input_action(text) - def input_action(self,text): + def input_action(self, text): self.get_web_element().send_keys(text) @scenario(action_name="Send keys to the element") diff --git a/README.md b/README.md index af3f0f7..d96d055 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,17 @@ # JDI 2.0 Powerful Framework for UI Automation Testing on Python + +## Getting started +Before you begin: +- Python 3.11 is used for this project. To install Python on MacOs you can use [Homebrew](https://brew.sh/), on Windows you can use [Chocolatey](https://chocolatey.org/). +- run git clone https://github.com/jdi-testing/jdi-python.git or fork the repository and clone it afterwards. +- create a virtual environment for the project. You can use [virtualenv](https://virtualenv.pypa.io/en/latest/) or [venv](https://docs.python.org/3/library/venv.html) for that. +- set up Python interpreter to use Python 3.11 in your IDE. +- run `pip install -r requirements.txt` to install all required dependencies. + +## You can simply run tests to see how it works +1. inside your IDE +2. using pytest + - activate your virtual environment by running `source venv/bin/activate` on MacOs or `venv\Scripts\activate` on Windows + - run `pytest` in the terminal \ No newline at end of file diff --git a/jdi.properties b/jdi.properties index 7bd6377..77e4536 100644 --- a/jdi.properties +++ b/jdi.properties @@ -1,6 +1,6 @@ driver=chrome ; domain=https://www.epam.com/ -domain=https://jdi-framework.github.io/tests +domain=https://jdi-testing.github.io/jdi-light timeout_wait_element=5 timeout_wait_pageLoad=5 drivers_folder=.\ diff --git a/requirements.txt b/requirements.txt index 4579c61..5d76bce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ -pywin32==302 -selenium==3.141.0 -requests==2.25.1 +selenium==4.18.1 +requests==2.31.0 +pytest==8.1.1 +webdriver_manager==4.0.1 diff --git a/tests/jdi_uitests_webtests/main/entities/user.py b/tests/jdi_uitests_webtests/main/entities/user.py index 39ba2db..3d56408 100644 --- a/tests/jdi_uitests_webtests/main/entities/user.py +++ b/tests/jdi_uitests_webtests/main/entities/user.py @@ -7,8 +7,5 @@ def default(): return User() def __init__(self): - self.login = "epam" - self.password = os.getenv("TEST_PASSWORD") - self.name = "Name" - self.last_name = "Last Name" - self.description = "Description" + self.login = "Roman" + self.password = "Jdi1234" diff --git a/tests/jdi_uitests_webtests/main/enums/preconditions.py b/tests/jdi_uitests_webtests/main/enums/preconditions.py index 55ad12d..4e12f84 100644 --- a/tests/jdi_uitests_webtests/main/enums/preconditions.py +++ b/tests/jdi_uitests_webtests/main/enums/preconditions.py @@ -6,13 +6,13 @@ from JDI.web.selenium.preconditions.web_preconditions import WebPreconditions -class Preconditions(Enum): - HOME_PAGE = ("/index.htm",) - CONTACT_PAGE = ("/page1.htm",) - METALS_AND_COLORS_PAGE = ("/page2.htm",) - SUPPORT_PAGE = ("/page3.htm",) - DATES_PAGE = "/page4.htm" - SIMPLE_TABLE_PAGE = "/page6.htm" +class Preconditions(str, Enum): + HOME_PAGE = ("/index.html",) + CONTACT_PAGE = ("/contacts.html",) + METALS_AND_COLORS_PAGE = ("/metals-colors.html",) + SUPPORT_PAGE = ("/support.html",) + DATES_PAGE = "/dates.html" + SIMPLE_TABLE_PAGE = "/simple-table.html" def is_in_state(self): str_value = self.value[0] if isinstance(self.value, tuple) else self.value diff --git a/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py b/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py index 5634e21..6ba24d3 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py +++ b/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py @@ -1,6 +1,7 @@ from JDI.web.selenium.elements.api_interact.find_element_by import By from JDI.web.selenium.elements.complex.text_list import TextList from JDI.web.selenium.elements.composite.web_site import WebSite +from tests.jdi_uitests_webtests.main.enums.preconditions import Preconditions from tests.jdi_uitests_webtests.main.page_objects.pages import ( ContactFormPage, DatesPage, @@ -16,12 +17,15 @@ class EpamJDISite(WebSite): # pages - home_page = HomePage(url="/index.htm", title="Index Page") - metals_colors_page = MetalColorPage(url="/page2.htm", title="Metal and Colors") - contact_form_page = ContactFormPage(url="/page1.htm", title="Contact Form") - support_page = SupportPage(url="/page3.htm", title="Support") - dates_page = DatesPage(url="/page4.htm", title="Simple Table") - simple_table_page = SimpleTablePage(url="/page6.htm", title="Simple Table") + home_page = HomePage(url=Preconditions.HOME_PAGE.value, title="Index Page") + metals_colors_page = MetalColorPage(url=Preconditions.METALS_AND_COLORS_PAGE.value, + title="Metal and Colors") + contact_form_page = ContactFormPage(url=Preconditions.CONTACT_PAGE.value, + title="Contact Form") + support_page = SupportPage(url=Preconditions.SUPPORT_PAGE.value, title="Support") + dates_page = DatesPage(url=Preconditions.DATES_PAGE.value, title="Simple Table") + simple_table_page = SimpleTablePage(url=Preconditions.SIMPLE_TABLE_PAGE.value, + title="Simple Table") # elements actions_log = TextList(By.css(".logs li")) diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/login.py b/tests/jdi_uitests_webtests/main/page_objects/pages/login.py index 73e99ff..8a82c4c 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/pages/login.py +++ b/tests/jdi_uitests_webtests/main/page_objects/pages/login.py @@ -7,9 +7,9 @@ class Login(Form): - login = TextField(By.id("Login")) + login = TextField(By.id("name")) - password = TextField(By.id("Password")) + password = TextField(By.id("password")) button = Button(By.css(".btn-login")) From d3441fb93ad5a622f75af020271a5821e262e924 Mon Sep 17 00:00:00 2001 From: vklonin Date: Mon, 11 Mar 2024 18:18:54 +0300 Subject: [PATCH 02/29] fixed metals_color_page.py --- README.md | 3 ++- .../main/page_objects/pages/metals_color_page.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d96d055..cbbd510 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,5 @@ Before you begin: 1. inside your IDE 2. using pytest - activate your virtual environment by running `source venv/bin/activate` on MacOs or `venv\Scripts\activate` on Windows - - run `pytest` in the terminal \ No newline at end of file + - run `pytest` in the terminal (eg. `pytest ./tests/jdi_uitests_webtests/test/common/` - to run all tests in the specified directory) + - be sure that you are in a project root directory when running the command \ No newline at end of file diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py b/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py index 15b4f26..3a81199 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py +++ b/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py @@ -9,6 +9,7 @@ from JDI.web.selenium.elements.complex.dropdown import Dropdown from JDI.web.selenium.elements.composite.web_page import WebPage from tests.jdi_uitests_webtests.main.page_objects.sections.summary import Summary +from selenium.webdriver.common.by import By as strategy class CheckBoxMetalColor(CheckBox): @@ -16,7 +17,7 @@ def is_check_action(self): driver = JDISettings.get_driver_factory().get_driver() return ( False - if driver.find_element_by_xpath("//*[@id='elements-checklist']//*[*[text()='Water']]/input").get_attribute( + if driver.find_element(strategy.XPATH, "//*[@id='elements-checklist']//*[*[text()='Water']]/input").get_attribute( "checked" ) is None @@ -26,7 +27,7 @@ def is_check_action(self): class CheckListMetalColor(CheckList): def is_element_selected(self, el): - return el.find_element_by_xpath("../input").is_selected() + return el.find_element(strategy.XPATH, "../input").is_selected() class ComboBoxMetalColor(ComboBox): From 3c4b24960e9118bf03d3be55867fcdd8156e51e6 Mon Sep 17 00:00:00 2001 From: vklonin Date: Mon, 11 Mar 2024 18:34:57 +0300 Subject: [PATCH 03/29] fixed image tests --- .../selenium/elements/composite/web_page.py | 26 +++++++++---------- .../main/page_objects/epam_jdi_site.py | 2 +- .../test/common/image_test.py | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/JDI/web/selenium/elements/composite/web_page.py b/JDI/web/selenium/elements/composite/web_page.py index c9e0040..a58c1a0 100644 --- a/JDI/web/selenium/elements/composite/web_page.py +++ b/JDI/web/selenium/elements/composite/web_page.py @@ -70,27 +70,27 @@ def open(self): self.get_driver().get(self.url) def verify_opened(self): - result = False + url_check_passed = False if self.check_url_type == CheckPageTypes.EQUAL: - result = self.check_url() + url_check_passed = self.check_url() elif self.check_url_type == CheckPageTypes.MATCH: - result = self.match_url() + url_check_passed = self.match_url() elif self.check_url_type == CheckPageTypes.CONTAINS: - result = self.contains_url() - if not result: + url_check_passed = self.contains_url() + + if not url_check_passed: return False if self.title is None: return True - if self.check_title_type == CheckPageTypes.EQUAL: - return self.check_title() - if self.check_title_type == CheckPageTypes.MATCH: - return self.match_title() - if self.check_title_type == CheckPageTypes.CONTAINS: - return self.contains_title() - - return False + title_check_methods = { + CheckPageTypes.EQUAL: self.check_title, + CheckPageTypes.MATCH: self.match_title, + CheckPageTypes.CONTAINS: self.contains_title + } + title_check_method = title_check_methods.get(self.check_title_type, lambda: False) + return title_check_method() def should_be_opened(self): try: diff --git a/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py b/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py index 6ba24d3..10eed84 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py +++ b/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py @@ -17,7 +17,7 @@ class EpamJDISite(WebSite): # pages - home_page = HomePage(url=Preconditions.HOME_PAGE.value, title="Index Page") + home_page = HomePage(url=Preconditions.HOME_PAGE.value, title="Home Page") metals_colors_page = MetalColorPage(url=Preconditions.METALS_AND_COLORS_PAGE.value, title="Metal and Colors") contact_form_page = ContactFormPage(url=Preconditions.CONTACT_PAGE.value, diff --git a/tests/jdi_uitests_webtests/test/common/image_test.py b/tests/jdi_uitests_webtests/test/common/image_test.py index e3c5d10..34828be 100644 --- a/tests/jdi_uitests_webtests/test/common/image_test.py +++ b/tests/jdi_uitests_webtests/test/common/image_test.py @@ -9,7 +9,7 @@ @pytest.mark.web class ImageTests(InitTests): ALT = "ALT" - SRC = "https://jdi-framework.github.io/tests/images/Logo_Epam_Color.svg" + SRC = "https://jdi-testing.github.io/jdi-light/images/Logo_Epam_Color.svg" clickable_item = EpamJDISite.home_page.logo_image From 9af600190d8b6fa58a4891d651cc3e6a9d700069 Mon Sep 17 00:00:00 2001 From: vklonin Date: Tue, 12 Mar 2024 12:18:38 +0300 Subject: [PATCH 04/29] updated actions with 3 11 python --- .github/workflows/jdi-python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jdi-python.yml b/.github/workflows/jdi-python.yml index fc0b5d2..0cc7d85 100644 --- a/.github/workflows/jdi-python.yml +++ b/.github/workflows/jdi-python.yml @@ -15,7 +15,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.x'] + python-version: ['3.11'] steps: - uses: actions/checkout@v2 From cf096a1d5c499ca0c770fdaad4659740d164d474 Mon Sep 17 00:00:00 2001 From: vklonin Date: Tue, 12 Mar 2024 12:36:07 +0300 Subject: [PATCH 05/29] bumping deps --- requirements-dev.txt | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 8a9653f..df775d9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,31 +1,31 @@ appdirs==1.4.4 -astroid==2.4.2 -black==20.8b1 -certifi==2020.12.5 -chardet==4.0.0 -click==7.1.2 -colorama==0.4.4 -comtypes==1.1.8 -flake8==3.8.4 -idna==2.10 -isort==5.7.0 -lazy-object-proxy==1.4.3 -mccabe==0.6.1 -mypy==0.800 -mypy-extensions==0.4.3 -pathspec==0.8.1 -pycodestyle==2.6.0 -pyflakes==2.2.0 -pylint==2.6.0 -pyperclip==1.8.1 -pywin32==302 -regex==2020.11.13 -requests==2.25.1 -selenium==3.141.0 -six==1.15.0 +astroid==3.1.0 +black==24.2.0 +certifi==2024.2.2 +chardet==5.2.0 +click==8.1.7 +colorama==0.4.6 +comtypes==1.3.1 +flake8==7.0.0 +idna==3.6 +isort==5.13.2 +lazy-object-proxy==1.10.0 +mccabe==0.7.0 +mypy==1.9.0 +mypy-extensions==1.0.0 +pathspec==0.12.1 +pycodestyle==2.11.1 +pyflakes==3.2.0 +pylint==3.1.0 +pyperclip==1.8.2 +pywin32==306 +regex==2023.12.25 +requests==2.31.0 +selenium==4.18.1 +six==1.16.0 toml==0.10.2 -typed-ast==1.4.3 -typing-extensions==3.7.4.3 -wrapt==1.12.1 +typed-ast==1.5.5 +typing-extensions==4.10.0 +wrapt==1.16.0 pytest pytest-cov From 01c59536f38ae9fc8a42c35fa36d81b6d4486cda Mon Sep 17 00:00:00 2001 From: vklonin Date: Tue, 12 Mar 2024 13:00:42 +0300 Subject: [PATCH 06/29] testing Path beh --- tests/core/test_jdi_settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/core/test_jdi_settings.py b/tests/core/test_jdi_settings.py index b01ada8..9ab86f3 100644 --- a/tests/core/test_jdi_settings.py +++ b/tests/core/test_jdi_settings.py @@ -1,3 +1,4 @@ +import os from pathlib import Path import pytest @@ -15,4 +16,5 @@ def test_creation_with_param(self): assert p._filename.name == "test.txt" def test_get_property_file(self): + print(os.getcwd()) assert PropertyPath().get_property_file() == Path("jdi.properties") From 16513a8f6926335ec60ace7b494167dfc1b97aeb Mon Sep 17 00:00:00 2001 From: vklonin Date: Tue, 12 Mar 2024 13:14:11 +0300 Subject: [PATCH 07/29] testing Path beh --- tests/core/test_jdi_settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/test_jdi_settings.py b/tests/core/test_jdi_settings.py index 9ab86f3..4fece3c 100644 --- a/tests/core/test_jdi_settings.py +++ b/tests/core/test_jdi_settings.py @@ -15,6 +15,6 @@ def test_creation_with_param(self): p = PropertyPath("test.txt") assert p._filename.name == "test.txt" + @pytest.mark.skipif(os.getcwd() == os.path.dirname(__file__), reason="Tests require current directory to be the same as the test directory") def test_get_property_file(self): - print(os.getcwd()) - assert PropertyPath().get_property_file() == Path("jdi.properties") + assert PropertyPath().get_property_file() == Path("jdi.properties").absolute() From d9ef0250f78c1a9c0fc684b4b716f9c305999e24 Mon Sep 17 00:00:00 2001 From: vklonin Date: Tue, 12 Mar 2024 13:42:42 +0300 Subject: [PATCH 08/29] testing Path beh --- .github/workflows/jdi-python.yml | 4 ++++ utils/get_driver.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/jdi-python.yml b/.github/workflows/jdi-python.yml index 0cc7d85..fd1a95f 100644 --- a/.github/workflows/jdi-python.yml +++ b/.github/workflows/jdi-python.yml @@ -37,6 +37,10 @@ jobs: run: | pytest -v --cov=. --cov-config=.coveragerc --cov-report=html -m unit shell: cmd + - name: Run tests excluding unit tests + run: | + pytest -v -m "not unit" + shell: cmd - name: Save debug log file uses: actions/upload-artifact@v2 with: diff --git a/utils/get_driver.py b/utils/get_driver.py index 2098247..946892b 100644 --- a/utils/get_driver.py +++ b/utils/get_driver.py @@ -34,6 +34,6 @@ def compose_download_link(build) -> str: if __name__ == "__main__": - release = get_last_release("87.0.4280") + release = get_last_release() download_link = compose_download_link(build=release) download_driver(download_link) From cb77e07efbdb377bc2ab82da673418d06ea4801a Mon Sep 17 00:00:00 2001 From: vklonin Date: Wed, 13 Mar 2024 12:45:42 +0300 Subject: [PATCH 09/29] fixing tests on new site --- JDI/core/settings/jdi_settings.py | 11 ++++++++--- JDI/web/selenium/driver/selenium_driver_factory.py | 2 +- JDI/web/selenium/settings/web_settings.py | 10 ++++++++++ jdi.properties | 3 ++- .../main/site/epam/custom_elements/tree_dropdown.py | 3 ++- tests/jdi_uitests_webtests/main/entities/contact.py | 2 +- tests/jdi_uitests_webtests/main/enums/entities.py | 2 +- .../main/page_objects/pages/contact_form_page.py | 5 ++--- .../main/page_objects/pages/metals_color_page.py | 6 +++--- .../main/page_objects/sections/contact_form.py | 12 ++++++------ .../main/page_objects/sections/summary.py | 9 +++++---- .../test/complex/combo_box_test.py | 10 +++++----- .../jdi_uitests_webtests/test/composite/form_test.py | 3 +-- 13 files changed, 47 insertions(+), 31 deletions(-) diff --git a/JDI/core/settings/jdi_settings.py b/JDI/core/settings/jdi_settings.py index ef058dc..92a7148 100644 --- a/JDI/core/settings/jdi_settings.py +++ b/JDI/core/settings/jdi_settings.py @@ -1,6 +1,5 @@ -import os -from pathlib import Path, PurePath import logging +from pathlib import Path logger = logging.getLogger(__name__) @@ -47,7 +46,13 @@ def get_driver_path(): def get_setting_by_name(setting_name): if not JDISettings._jdi_settings: JDISettings._read_jdi_settings() - return JDISettings._jdi_settings.get(setting_name, None) + value = JDISettings._jdi_settings.get(setting_name, None) + if value.lower() in ("true", "yes", "1"): + return True + elif value.lower() in ("false", "no", "0"): + return False + else: + return value @staticmethod def get_current_timeout_sec(): diff --git a/JDI/web/selenium/driver/selenium_driver_factory.py b/JDI/web/selenium/driver/selenium_driver_factory.py index a8303a7..313a0e0 100644 --- a/JDI/web/selenium/driver/selenium_driver_factory.py +++ b/JDI/web/selenium/driver/selenium_driver_factory.py @@ -40,7 +40,7 @@ def set_driver_options_and_capabilities(self, driver_name, options, capabilities self.capabilities = capabilities def add_options(self, options): - for arg in options: + for arg in options.arguments: self.options.add_argument(arg) def register_chrome_driver(self): diff --git a/JDI/web/selenium/settings/web_settings.py b/JDI/web/selenium/settings/web_settings.py index a12b86b..1753064 100644 --- a/JDI/web/selenium/settings/web_settings.py +++ b/JDI/web/selenium/settings/web_settings.py @@ -4,6 +4,8 @@ from JDI.core.settings.jdi_settings import JDISettings from JDI.web.selenium.driver.selenium_driver_factory import \ SeleniumDriverFactory +from selenium.webdriver.chrome.options import Options as ChromeOptions +from selenium.webdriver.firefox.options import Options as FirefoxOptions class WebSettings(JDISettings): @@ -21,6 +23,14 @@ def set_driver_factory(driver_factory): @staticmethod def use_driver(options=None, capabilities=None, executor=None): + if options is None: + options = ChromeOptions() if JDISettings.get_setting_by_name( + "driver") == "chrome" else FirefoxOptions() + + headless = JDISettings.get_setting_by_name("headless") + + if headless: + options.add_argument("--headless") driver_name = JDISettings.get_setting_by_name("driver") JDISettings._driver_factory = SeleniumDriverFactory() WebSettings.set_driver_factory(JDISettings._driver_factory) diff --git a/jdi.properties b/jdi.properties index 77e4536..7807aae 100644 --- a/jdi.properties +++ b/jdi.properties @@ -4,4 +4,5 @@ domain=https://jdi-testing.github.io/jdi-light timeout_wait_element=5 timeout_wait_pageLoad=5 drivers_folder=.\ -driver_getLatest=true \ No newline at end of file +driver_getLatest=true +headless=False \ No newline at end of file diff --git a/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py b/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py index 65dca52..ee28275 100644 --- a/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py +++ b/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py @@ -2,6 +2,7 @@ from JDI.web.selenium.elements.complex.base_selector import BaseSelector from JDI.web.selenium.elements.complex.dropdown import Dropdown +from selenium.webdriver.common.by import By as Strategy class TreeDropdown(Dropdown): @@ -27,5 +28,5 @@ def select_action(self, names): el.set_parent(self) web_el = el.get_element(split[i]) - if "dropdown-invisible-group" not in web_el.find_element_by_xpath("..").get_attribute("class"): + if "dropdown-invisible-group" not in web_el.find_element(Strategy.XPATH, "..").get_attribute("class"): web_el.click() diff --git a/tests/jdi_uitests_webtests/main/entities/contact.py b/tests/jdi_uitests_webtests/main/entities/contact.py index cd524d6..d4d66af 100644 --- a/tests/jdi_uitests_webtests/main/entities/contact.py +++ b/tests/jdi_uitests_webtests/main/entities/contact.py @@ -5,6 +5,6 @@ def __init__(self, name, last_name, description): self.description = description def __str__(self): - return "Summary: 3\nName: {0}\nLast Name: {1}\nDescription: {2}".format( + return "Summary: 3\nLast Name: {1}\nDescription: {2}\nVegetables:".format( self.first_name, self.last_name, self.description ) diff --git a/tests/jdi_uitests_webtests/main/enums/entities.py b/tests/jdi_uitests_webtests/main/enums/entities.py index dc12390..729c193 100644 --- a/tests/jdi_uitests_webtests/main/enums/entities.py +++ b/tests/jdi_uitests_webtests/main/enums/entities.py @@ -9,7 +9,7 @@ class Nature(Enum): class Metals(Enum): - COL = "Col" + METALS = "Metals" GOLD = "Gold" SILVER = "Silver" BRONZE = "Bronze" diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py b/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py index 8cb47b5..f2749a4 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py +++ b/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py @@ -2,7 +2,6 @@ from JDI.web.selenium.elements.common.text_area import TextArea from JDI.web.selenium.elements.common.text_field import TextField from JDI.web.selenium.elements.composite.web_page import WebPage -from tests.jdi_uitests_webtests.main.entities.contact import Contact from tests.jdi_uitests_webtests.main.page_objects.sections.contact_form import ContactForm, ContactFormTwoButtons @@ -10,9 +9,9 @@ class ContactFormPage(WebPage): def __init__(self, url, title): super(ContactFormPage, self).__init__(url=url, title=title) - description = TextArea(By.id("Description")) + description = TextArea(By.id("description")) - name_text_field = TextField(By.id("Name")) + name_text_field = TextField(By.id("first-name")) contact_form = ContactForm(By.css("main form")) diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py b/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py index 3a81199..5951728 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py +++ b/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py @@ -9,7 +9,7 @@ from JDI.web.selenium.elements.complex.dropdown import Dropdown from JDI.web.selenium.elements.composite.web_page import WebPage from tests.jdi_uitests_webtests.main.page_objects.sections.summary import Summary -from selenium.webdriver.common.by import By as strategy +from selenium.webdriver.common.by import By as Strategy class CheckBoxMetalColor(CheckBox): @@ -17,7 +17,7 @@ def is_check_action(self): driver = JDISettings.get_driver_factory().get_driver() return ( False - if driver.find_element(strategy.XPATH, "//*[@id='elements-checklist']//*[*[text()='Water']]/input").get_attribute( + if driver.find_element(Strategy.XPATH, "//*[@id='elements-checklist']//*[*[text()='Water']]/input").get_attribute( "checked" ) is None @@ -27,7 +27,7 @@ def is_check_action(self): class CheckListMetalColor(CheckList): def is_element_selected(self, el): - return el.find_element(strategy.XPATH, "../input").is_selected() + return el.find_element(Strategy.XPATH, "../input").is_selected() class ComboBoxMetalColor(ComboBox): diff --git a/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py b/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py index 7652f8b..33c15ea 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py +++ b/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py @@ -9,9 +9,9 @@ class ContactForm(Form): def __init__(self, by_locator=None): super(ContactForm, self).__init__(by_locator) - first_name = TextField(By.id("Name")) - last_name = TextField(By.id("LastName")) - description = TextArea(By.id("Description")) + first_name = TextField(By.id("first-name")) + last_name = TextField(By.id("last-name")) + description = TextArea(By.id("description")) submit = Button(By.xpath("//*[text()='Submit']")) @@ -23,9 +23,9 @@ class ContactFormTwoButtons(Form): def __init__(self, by_locator=None): super(ContactFormTwoButtons, self).__init__(by_locator) - first_name = TextField(By.id("Name")) - last_name = TextField(By.id("LastName")) - description = TextArea(By.id("Description")) + first_name = TextField(By.id("first-name")) + last_name = TextField(By.id("last-name")) + description = TextArea(By.id("description")) submit = Button(By.xpath("//*[text()='Submit']")) calculate = Button(By.xpath("//*[text()='Calculate']")) diff --git a/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py b/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py index ba3e311..fbabac3 100644 --- a/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py +++ b/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py @@ -5,6 +5,7 @@ from JDI.web.selenium.elements.complex.radio_buttons import RadioButtons from JDI.web.selenium.elements.complex.selector import Selector from JDI.web.selenium.elements.composite.section import Section +from selenium.webdriver.common.by import By as Strategy ERROR_MSG = "No elements selected. Override getSelectedAction or place locator to