Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bumping dependencies and test site #69

Merged
merged 29 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions .github/workflows/jdi-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,32 @@ on:
jobs:
build:

runs-on: windows-latest
runs-on: ubuntu-latest
strategy:
matrix:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

лучше на ubuntu, быстрее работать будет

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

переключил

python-version: ['3.7', '3.8', '3.x']
python-version: ['3.11']
browser: [chrome, firefox]

steps:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actions/setup-python@v5 тоже

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сделал

- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Download Chrome driver
run: |
cd utils
python get_driver.py
# TODO: use virtual machine for tests run
- name: Run unit tests
run: |
pytest -v --cov=. --cov-config=.coveragerc --cov-report=html -m unit
shell: cmd
shell: bash
- name: Run tests excluding 'unit' tests on ${{ matrix.browser }}
run: |
pytest -v -m "not unit" --browser=${{ matrix.browser }}
shell: bash
- name: Save debug log file
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: logs
path: debug.log
Expand Down
6 changes: 1 addition & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand All @@ -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=<password>`

```bash
pytest <path to the project>/tests --no-header --no-summary -q
```
Expand Down
18 changes: 12 additions & 6 deletions JDI/core/settings/jdi_settings.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
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:
Expand Down Expand Up @@ -46,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():
Expand Down
53 changes: 25 additions & 28 deletions JDI/web/selenium/driver/selenium_driver_factory.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import os

from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.firefox.webdriver import WebDriver as FirefoxDriver
from selenium.webdriver.remote.webdriver import WebDriver as RemoteDriver
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.firefox import GeckoDriverManager

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:
Expand All @@ -17,7 +19,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):
Expand All @@ -28,64 +29,60 @@ 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:
elif 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:
elif 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.options.add_argument("-start-maximized")
if options:
self.add_options(options)
if not capabilities and executor is None:
self.capabilities = DesiredCapabilities.FIREFOX
if 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):
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))
service = Service(ChromeDriverManager().install())
return self.__web_driver_settings(ChromeDriver(service=service, options=self.options))

def register_firefox_driver(self):
raise NotImplementedError
service = FirefoxService(GeckoDriverManager().install())
return self.__web_driver_settings(FirefoxDriver(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,
options=self.options,
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
10 changes: 4 additions & 6 deletions JDI/web/selenium/driver/web_driver_provider.py
Original file line number Diff line number Diff line change
@@ -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

2 changes: 1 addition & 1 deletion JDI/web/selenium/elements/common/text_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
26 changes: 13 additions & 13 deletions JDI/web/selenium/elements/composite/web_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
18 changes: 17 additions & 1 deletion JDI/web/selenium/settings/web_settings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import sys

from selenium.webdriver.remote.command import Command

from JDI.core.logger.jdi_logger import JDILogger
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):
Expand All @@ -21,7 +25,19 @@ def set_driver_factory(driver_factory):

@staticmethod
def use_driver(options=None, capabilities=None, executor=None):
driver_name = JDISettings.get_setting_by_name("driver")
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 = next(
(arg.split("=")[1] for arg in sys.argv if arg.startswith("--browser")),
JDISettings.get_setting_by_name("driver"))

JDISettings._driver_factory = SeleniumDriverFactory()
WebSettings.set_driver_factory(JDISettings._driver_factory)
return JDISettings._driver_factory.register_driver(driver_name, options, capabilities, executor)
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@

# 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 (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
7 changes: 5 additions & 2 deletions jdi.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
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=.\
driver_getLatest=true
driver_getLatest=true
headless=True
user=Roman
password=Jdi1234
4 changes: 3 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[pytest]
markers =
unit: marks unit tests
web: marks JDI tests
web: marks JDI tests
log_cli = true
log_cli_level = INFO
2 changes: 2 additions & 0 deletions requirements-dev-win.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-r requirements-dev.txt
pywin32==306
Loading
Loading