Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 19 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[dependency-groups]
dev = [
"ruff==0.11.8",
"pre-commit==4.2.0"
]

[project]
authors = [{name = "Nir Tal", email = "nirt236@gmail.com"}]
name = "selenium-python-example"
description = "Selenium Python example project with pytest and Allure report"
version = "0.1.0"
dependencies = [
"allure-pytest==2.14.1",
"assertpy==1.1",
Expand All @@ -32,23 +30,10 @@ dependencies = [
"visual-regression-tracker==4.9.0",
"xlrd==2.0.1"
]
description = "Selenium Python example project with pytest and Allure report"
name = "selenium-python-example"
readme = "README.md"
requires-python = "~=3.11"
version = "0.1.0"

[project.urls]
Homepage = "https://github.com/nirtal85/Selenium-Python-Example"
Repository = "https://github.com/nirtal85/Selenium-Python-Example"

[tool.hatch.build.targets.sdist]
include = ["selenium_python_example"]

[tool.hatch.build.targets.wheel]
include = ["selenium_python_example"]

[tool.pytest.ini_options]
pythonpath = ["src"]
addopts = [
"--clean-alluredir",
"--alluredir=allure-results",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion pages/about_page.py → src/pages/about_page.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import allure
from selenium.webdriver.common.by import By

from pages.base_page import BasePage
from src.pages.base_page import BasePage


class AboutPage(BasePage):
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import allure
from selenium.webdriver.common.by import By

from pages.base_page import BasePage
from src.pages.base_page import BasePage


class ForgotPasswordPage(BasePage):
Expand Down
2 changes: 1 addition & 1 deletion pages/login_page.py → src/pages/login_page.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import allure
from selenium.webdriver.common.by import By

from pages.top_bars.top_menu_bar import TopMenuBar
from src.pages.top_bars.top_menu_bar import TopMenuBar


class LoginPage(TopMenuBar):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import allure
from selenium.webdriver.common.by import By

from pages.base_page import BasePage
from src.pages.base_page import BasePage


class ProjectEditPage(BasePage):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

from pages.top_bars.top_navigate_bar import TopNavigateBar
from src.pages.top_bars.top_navigate_bar import TopNavigateBar


class ProjectTypePage(TopNavigateBar):
Expand Down
4 changes: 2 additions & 2 deletions pages/projects_page.py → src/pages/projects_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

from enums.status import Status
from pages.top_bars.top_navigate_bar import TopNavigateBar
from src.enums.status import Status
from src.pages.top_bars.top_navigate_bar import TopNavigateBar


class ProjectsPage(TopNavigateBar):
Expand Down
2 changes: 1 addition & 1 deletion pages/templates_page.py → src/pages/templates_page.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

from pages.top_bars.top_navigate_bar import TopNavigateBar
from src.pages.top_bars.top_navigate_bar import TopNavigateBar


class TemplatesPage(TopNavigateBar):
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import allure
from selenium.webdriver.common.by import By

from pages.base_page import BasePage
from src.pages.base_page import BasePage


class TopMenuBar(BasePage):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import allure
from selenium.webdriver.common.by import By

from pages.base_page import BasePage
from src.pages.base_page import BasePage


class TopNavigateBar(BasePage):
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import xlrd

from utilities.constants import Constants
from src.utilities.constants import Constants


class ExcelParser:
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion utilities/vrt_helper.py → src/utilities/vrt_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from selenium.webdriver.support.wait import WebDriverWait
from visual_regression_tracker import IgnoreArea, TestRun, TestRunStatus, VisualRegressionTracker

from utilities.constants import Constants
from src.utilities.constants import Constants


class VrtHelper:
Expand Down
File renamed without changes.
18 changes: 9 additions & 9 deletions tests/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
from selenium.webdriver import Chrome, Edge, Firefox
from selenium.webdriver.support.wait import WebDriverWait

from pages.about_page import AboutPage
from pages.forgot_password_page import ForgotPasswordPage
from pages.login_page import LoginPage
from pages.project_edit_page import ProjectEditPage
from pages.project_type_page import ProjectTypePage
from pages.projects_page import ProjectsPage
from pages.templates_page import TemplatesPage
from utilities.mailinator_helper import MailinatorHelper
from utilities.vrt_helper import VrtHelper
from src.pages.about_page import AboutPage
from src.pages.forgot_password_page import ForgotPasswordPage
from src.pages.login_page import LoginPage
from src.pages.project_edit_page import ProjectEditPage
from src.pages.project_type_page import ProjectTypePage
from src.pages.projects_page import ProjectsPage
from src.pages.templates_page import TemplatesPage
from src.utilities.mailinator_helper import MailinatorHelper
from src.utilities.vrt_helper import VrtHelper


class BaseTest(ABC):
Expand Down
26 changes: 13 additions & 13 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@
from selenium.webdriver.support.wait import WebDriverWait
from visual_regression_tracker import VisualRegressionTracker

from pages.about_page import AboutPage
from pages.forgot_password_page import ForgotPasswordPage
from pages.login_page import LoginPage
from pages.project_edit_page import ProjectEditPage
from pages.project_type_page import ProjectTypePage
from pages.projects_page import ProjectsPage
from pages.templates_page import TemplatesPage
from utilities.constants import Constants
from utilities.data import Data
from utilities.excel_parser import ExcelParser
from utilities.mailinator_helper import MailinatorHelper
from utilities.vrt_helper import VrtHelper
from utilities.web_driver_listener import DriverEventListener
from src.pages.about_page import AboutPage
from src.pages.forgot_password_page import ForgotPasswordPage
from src.pages.login_page import LoginPage
from src.pages.project_edit_page import ProjectEditPage
from src.pages.project_type_page import ProjectTypePage
from src.pages.projects_page import ProjectsPage
from src.pages.templates_page import TemplatesPage
from src.utilities.constants import Constants
from src.utilities.mailinator_helper import MailinatorHelper
from src.utilities.web_driver_listener import DriverEventListener
from src.utilities.excel_parser import ExcelParser
from src.utilities.data import Data
from src.utilities.vrt_helper import VrtHelper

drivers = ("chrome", "firefox", "chrome_headless", "remote")

Expand Down
2 changes: 1 addition & 1 deletion tests/db_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@pytest.mark.skip(reason="requires database connection")
class TestDatabaseExample:
@allure.title("Verify population amounts")
def test_verify_population_amount(self, db_connection):
def test_verify_population_amount(self, db_connection) -> None:
with db_connection.cursor() as cursor:
cursor.execute("SELECT Population FROM city WHERE CountryCode='DNK'")
population_amount = [item[0] for item in cursor.fetchall()]
Expand Down
2 changes: 1 addition & 1 deletion tests/dependency_class_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TestDependencyExample(BaseTest):
classes.
"""

def test_e(self):
def test_e(self) -> None:
"""Placeholder test function with the dependency name "e" and depends on "TestDependencyExample::b".
This test case is designed for demonstration purposes only.
Expand Down
8 changes: 4 additions & 4 deletions tests/dependency_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ class TestDependencyExample(BaseTest):
"""

@pytest.mark.dependency(name="a")
def test_a(self):
def test_a(self) -> None:
pass

@pytest.mark.dependency(name="b")
def test_b(self):
def test_b(self) -> None:
assert False

@pytest.mark.dependency(name="c", depends=["b"])
def test_c(self):
def test_c(self) -> None:
pass

@pytest.mark.dependency(name="d", depends=["b", "c"])
def test_d(self):
def test_d(self) -> None:
pass
6 changes: 3 additions & 3 deletions tests/email_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
@pytest.mark.skip(reason="requires mailinator client")
class TestEmail(BaseTest):
@allure.title("Verify email count in user inbox")
def test_verify_email_count(self, mailinator_helper):
def test_verify_email_count(self, mailinator_helper) -> None:
subject_counts = mailinator_helper.count_messages_by_subject("testautomation")
TestCase().assertDictEqual({"some subject": 1}, subject_counts)

@allure.title("Verify email content")
def test_verify_email_body(self, mailinator_helper):
def test_verify_email_body(self, mailinator_helper) -> None:
message = mailinator_helper.get_message("testautomation", "purchase is confirmed")
assert "Thank you for your purchase" in message.parts[0].body

@allure.title("Get OTP code from email")
def test_verify_otp_code(self, mailinator_helper):
def test_verify_otp_code(self, mailinator_helper) -> None:
otp_code = mailinator_helper.get_otp_code("testautomation")
assert otp_code.isdigit(), f"OTP code '{otp_code}' is not a digit string"
assert len(otp_code) == 6, f"OTP code '{otp_code}' is not 6 digits long"
8 changes: 4 additions & 4 deletions tests/forgot_password_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import pytest
from assertpy import assert_that

from src.utilities.data import Data
from tests.base_test import BaseTest
from utilities.data import Data


@allure.epic("Security")
Expand All @@ -18,7 +18,7 @@
class TestForgotPassword(BaseTest):
@allure.description("Forgot password with a valid email address")
@allure.title("Forgot Password with valid email test")
def test_valid_email(self, data: Data):
def test_valid_email(self, data: Data) -> None:
self.about_page.click_login_link()
self.login_page.click_forgot_password()
self.forget_password_page.send_password_reset_link(os.getenv("EMAIL"))
Expand All @@ -32,7 +32,7 @@ def test_valid_email(self, data: Data):
"'involve' in config.getoption('base_url')",
reason="Conditional skip based on base url",
)
def test_invalid_email(self, excel_reader, data: Data):
def test_invalid_email(self, excel_reader, data: Data) -> None:
"""This test is an example of a conditional skip based on base url."""
emails = excel_reader.read_from_excel("Emails")
self.about_page.click_login_link()
Expand All @@ -47,7 +47,7 @@ def test_invalid_email(self, excel_reader, data: Data):
@allure.link("github.com/allure-examples/", name="Allure Examples")
@allure.issue("github.com/allure-examples/allure-examples/issues/1", name="ISSUE-1")
@allure.testcase("github.com/allure-examples/allure-examples/issues/2", name="TESTCASE-2")
def test_expected_exception_on_page_title(self):
def test_expected_exception_on_page_title(self) -> None:
self.about_page.click_login_link()
self.login_page.click_forgot_password()
with pytest.raises(AssertionError) as e:
Expand Down
14 changes: 7 additions & 7 deletions tests/login_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from assertpy import assert_that

from tests.base_test import BaseTest
from utilities.constants import Constants
from utilities.data import Data
from src.utilities.constants import Constants
from src.utilities.data import Data

users = [("nirt236@gmail.com", "123456"), ("elias@gmail.com", "12345Tr")]

Expand All @@ -22,7 +22,7 @@ class TestLogin(BaseTest):
@allure.title("Login with invalid credentials test")
@pytest.mark.parametrize("email, password", users)
@pytest.mark.run(order=3)
def test_invalid_login(self, email: str, password: str, data: Data):
def test_invalid_login(self, email: str, password: str, data: Data) -> None:
self.about_page.click_login_link()
self.login_page.login(email, password)
assert_that(self.login_page.get_error_message()).described_as(
Expand All @@ -31,14 +31,14 @@ def test_invalid_login(self, email: str, password: str, data: Data):

@allure.description("Basic sanity")
@pytest.mark.devRun
def test_sanity(self, base_url):
def test_sanity(self, base_url) -> None:
assert_that(self.driver.current_url).described_as("URL").is_equal_to(base_url)

@allure.description("valid login")
@allure.title("Login with valid credentials test")
@allure.tag("Tagged test")
@pytest.mark.flaky(reruns=1)
def test_valid_login(self, data: Data):
def test_valid_login(self, data: Data) -> None:
self.about_page.set_geo_location(30.3079823, -97.893803)
self.about_page.click_login_link()
self.login_page.login(os.getenv("EMAIL"), os.getenv("PASSWORD"))
Expand All @@ -49,7 +49,7 @@ def test_valid_login(self, data: Data):
@allure.description("Log out from app")
@allure.title("Logout of system test")
@allure.story("As a user I want to be able to logout after a successful login.")
def test_logout(self, data: Data):
def test_logout(self, data: Data) -> None:
"""Test case to verify the logout functionality.

:param data: An instance of the Data dataclass containing test data.
Expand Down Expand Up @@ -136,5 +136,5 @@ def test_logout(self, data: Data):
@allure.title("Skipped test example")
@allure.label("owner", "nir tal")
@pytest.mark.skip(reason="skip test example")
def test_skip(self):
def test_skip(self) -> None:
pass
6 changes: 3 additions & 3 deletions tests/visual_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
@pytest.mark.skip(reason="requires a running VRT server")
class TestVisual(BaseTest):
@allure.title("Visual test of login page")
def test_shoot_page(self, vrt_helper):
def test_shoot_page(self, vrt_helper) -> None:
vrt_helper.shoot_page("page baseline")

@allure.title("Visual test of login page with ignored area")
def test_shoot_page_with_ignore_area(self, vrt_helper):
def test_shoot_page_with_ignore_area(self, vrt_helper) -> None:
element_to_ignore: WebElement = self.wait.until(
expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, "h1"))
)
Expand All @@ -27,5 +27,5 @@ def test_shoot_page_with_ignore_area(self, vrt_helper):
)

@allure.title("Visual test of login page element")
def test_shoot_element(self, vrt_helper):
def test_shoot_element(self, vrt_helper) -> None:
vrt_helper.shoot_element("element baseline", (By.CSS_SELECTOR, "h1"))
Loading
Loading