diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..6f64542
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,119 @@
+name: Python Selenium Tests with Allure Report
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ build:
+ name: 'Run Pytest + Generate Allure Report'
+ runs-on: ubuntu-latest
+
+ steps:
+ # 1 Checkout repository
+ - name: Checkout repository
+ uses: actions/checkout@v4.2.2
+
+ # 2 Set up Python
+ - name: Set up Python
+ uses: actions/setup-python@v5.2.0
+ with:
+ python-version: '3.12'
+
+ # 3 Set up Chrome for Selenium
+ - name: Set up Chrome and Chromedriver
+ uses: browser-actions/setup-chrome@v1
+
+ # 4 Install dependencies
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+ pip install allure-pytest
+
+ # 5 Verify installed packages
+ - name: Verify installed packages
+ run: pip freeze
+
+ # 6 Run tests with Allure results
+ - name: Run tests
+ run: |
+ pytest --alluredir=allure-results --disable-warnings -q
+
+ - name: Install Allure
+ run: |
+ sudo apt-add-repository ppa:qameta/allure -y
+ sudo apt-get update
+ sudo apt-get install allure -y
+
+ # 7 Generate Allure report
+ - name: Generate Allure report
+ run: |
+ allure generate allure-results --clean -o allure-report
+
+ # 8 Upload screenshots (optional)
+ - name: Upload screenshots
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: screenshots
+ path: screenshots
+
+ # 9 Upload Allure report as artifact
+ - name: Upload Allure report
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: allure-report
+ path: allure-report
+
+ # 10 Get previous Allure history for gh-pages
+ - name: Get Allure history
+ uses: actions/checkout@v4
+ if: always()
+ continue-on-error: true
+ with:
+ ref: gh-pages
+ path: gh-pages
+
+ # 11 Build Allure report for Pages
+ - name: Build Allure report for GitHub Pages
+ if: always()
+ uses: simple-elf/allure-report-action@master
+ id: allure-report
+ with:
+ allure_results: allure-results
+ gh_pages: gh-pages
+ allure_report: allure-report
+ allure_history: allure-history
+ ref: gh-pages
+ path: gh-pages
+ keep_reports: 30
+
+ # 12 Publish Allure report to GitHub Pages
+ - name: Publish Allure report to GitHub Pages
+ if: always()
+ uses: peaceiris/actions-gh-pages@v4
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: allure-history
+ force_orphan: true
+
+ # 13 Save logs if not-success
+ - name: Save test logs
+ if: failure()
+ run: |
+ pytest --log-cli-level=INFO --capture=tee-sys --disable-warnings > pytest.log || true
+ shell: bash
+
+ # 14 Loading logs as artifacts
+ - name: Upload logs
+ if: failure()
+ uses: actions/upload-artifact@v4.4.3
+ with:
+ name: pytest-logs
+ path: pytest.log
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index ada9db8..3a6ba70 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.venv
.idea
+.idea/
*.log
__pycache__
allure-results
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index fe2c703..e6eb8b7 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,24 +5,12 @@
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
@@ -38,6 +26,11 @@
+
@@ -55,15 +48,19 @@
"keyToString": {
"Python tests.Python tests for home_page_test.test_get_url.executor": "Run",
"Python tests.Python tests for home_page_test.test_gotoElements_page.executor": "Run",
+ "Python tests.Python tests for tests.home_page_test.HomePageTest.executor": "Run",
+ "Python tests.Python tests for tests.home_page_test.HomePageTest.test_get_url.executor": "Run",
"Python tests.Python tests for tests.home_page_test.test_get_url.executor": "Run",
"Python tests.Python tests for tests.home_page_test.test_goto_elements_page.executor": "Run",
+ "Python tests.Python tests for tests.test_fixture.TestMainPage1.executor": "Run",
+ "Python tests.Python tests for tests.test_fixture.TestMainPage1.test_guest_should_see_login_link.executor": "Run",
"Python tests.Python tests for tests.text_box_test.test_text_box.executor": "Run",
"Python.home_page_test.executor": "Run",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
- "git-widget-placeholder": "main",
+ "git-widget-placeholder": "test__demoqa",
"settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable"
}
}
@@ -74,45 +71,38 @@
-
-
+
+
-
-
-
-
+
-
-
-
-
-
-
-
+
+
+
-
+
-
+
-
+
-
+
@@ -123,11 +113,11 @@
-
+
-
+
@@ -138,11 +128,11 @@
-
+
-
+
@@ -153,17 +143,17 @@
-
+
-
-
-
-
+
+
+
+
diff --git a/conftest.py b/conftest.py
index 847e2ce..a2f20ce 100644
--- a/conftest.py
+++ b/conftest.py
@@ -1,3 +1,7 @@
+import shutil
+import tempfile
+
+import os
import pytest
from selenium import webdriver
@@ -7,17 +11,47 @@
@pytest.fixture(scope="function")
def driver():
- # === BEFORE test ===
- chrome_options = webdriver.ChromeOptions()
- chrome_options.add_argument("--incognito")
- chrome_options.add_argument("--window-size = 1400, 1080")
- service_properties = Service(executable_path=ChromeDriverManager().install())
- driver = webdriver.Chrome(service=service_properties, options=chrome_options)
+ chrome_options = webdriver.ChromeOptions() # <-- исправлено
+
+ # Check run in CI (GitHub Actions)
+ is_ci = os.environ.get("CI") == "true"
+
+ if is_ci:
+ # === For CI ===
+ chrome_options.add_argument("--headless=new")
+ chrome_options.add_argument("--no-sandbox")
+ chrome_options.add_argument("--disable-dev-shm-usage")
+ chrome_options.add_argument("--disable-gpu")
+ chrome_options.add_argument("--window-size=1920,1080")
+ chrome_options.add_argument("--disable-software-rasterizer")
+ chrome_options.add_argument("--remote-debugging-port=9222")
+ chrome_options.add_argument("--disable-extensions")
+ chrome_options.add_argument("--disable-infobars")
+ chrome_options.add_argument("--disable-browser-side-navigation")
+ chrome_options.add_argument("--disable-features=VizDisplayCompositor")
+
+ # uniq profile
+ user_data_dir = tempfile.mkdtemp()
+ chrome_options.add_argument(f"--user-data-dir={user_data_dir}")
+ else:
+ # === Local run ===
+ chrome_options.add_argument("--incognito")
+ chrome_options.add_argument("--window-size=1400,1080")
+
+ # Create driver
+ service = Service(ChromeDriverManager().install())
+ driver = webdriver.Chrome(service=service, options=chrome_options)
+ driver.set_page_load_timeout(60)
+ driver.implicitly_wait(10)
yield driver
driver.quit()
+ if is_ci:
+ shutil.rmtree(user_data_dir, ignore_errors=True)
+
+
# === AFTER test ===
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
diff --git a/pages/elements/text_box_page.py b/pages/elements/text_box_page.py
index 1c3faf4..8cf56f0 100644
--- a/pages/elements/text_box_page.py
+++ b/pages/elements/text_box_page.py
@@ -22,7 +22,6 @@ def submit_data(self):
def check_result(self):
self.driver.implicitly_wait(6)
get_text_name = self.driver.find_element(By.ID, LocatorsTextBox.name).text
- # self.wait5().until(lambda _ : get_text_name.is_displayed())
return get_text_name
diff --git a/pytest.ini b/pytest.ini
index 91021f9..923acb2 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,3 +1,6 @@
[pytest]
addopts = --alluredir allure-results
- --clean-alluredir
\ No newline at end of file
+ --clean-alluredir
+markers =
+ smoke: marker for smoke
+ regression: marker for regression tests
\ No newline at end of file
diff --git a/tests/home_page_test.py b/tests/home_page_test.py
index d71afff..1c1f260 100644
--- a/tests/home_page_test.py
+++ b/tests/home_page_test.py
@@ -1,3 +1,5 @@
+import pytest
+
from pages.elements.elements_page import ElementsPage
from pages.home_page import HomePage
from conftest import driver
@@ -9,15 +11,17 @@
@allure.story("Homepage")
def test_get_url(driver):
home_page = HomePage(driver)
- home_page.open()\
- .get_title()
+ home_page.open() \
+ .get_title()
+# @pytest.mark.smoke
def test_goto_elements_page(driver):
- title = HomePage(driver)\
- .open()\
- .scroll_page()\
- .goto_elements_page\
- .get_title()
+ title = HomePage(driver) \
+ .open() \
+ .scroll_page() \
+ .goto_elements_page \
+ .get_title()
assert title.__eq__("DEMOQA")
+
diff --git a/tests/test_fixture.py b/tests/test_fixture.py
new file mode 100644
index 0000000..bb8c139
--- /dev/null
+++ b/tests/test_fixture.py
@@ -0,0 +1,26 @@
+import pytest
+from selenium import webdriver
+from selenium.webdriver.common.by import By
+
+link = "http://selenium1py.pythonanywhere.com/"
+
+
+@pytest.fixture
+def browser():
+ print("\nstart browser for test..")
+ browser = webdriver.Chrome()
+ yield browser
+ # этот код выполнится после завершения теста
+ print("\nquit browser..")
+ browser.quit()
+
+
+class TestMainPage1():
+ # вызываем фикстуру в тесте, передав ее как параметр
+ def test_guest_should_see_login_link(self, browser):
+ browser.get(link)
+ browser.find_element(By.CSS_SELECTOR, "#login_link")
+
+ def test_guest_should_see_basket_link_on_the_main_page(self, browser):
+ browser.get(link)
+ browser.find_element(By.CSS_SELECTOR, ".basket-mini .btn-group > a")
diff --git a/tests/text_box_test.py b/tests/text_box_test.py
index 02844ba..2c428ab 100644
--- a/tests/text_box_test.py
+++ b/tests/text_box_test.py
@@ -1,7 +1,9 @@
+import pytest
from pages.home_page import HomePage
name = "Ola"
+@pytest.mark.regression
def test_text_box(driver):
result: str = HomePage(driver)\
.open() \