diff --git a/.github/workflows/monthly.yml b/.github/workflows/monthly.yml index 226da5f2ac..263d2d0ec4 100644 --- a/.github/workflows/monthly.yml +++ b/.github/workflows/monthly.yml @@ -5,10 +5,10 @@ on: - cron: "0 0 1 * *" workflow_dispatch: inputs: - pytest_command: - description: "Custom pytest command" + pytest_marker: + description: "Pytest marker expression" required: true - default: '-m "not devRun"' + default: "not devRun" type: string parallelism: description: "Number of machines to split tests" @@ -31,10 +31,17 @@ jobs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - id: set-matrix + env: + PARALLELISM: ${{ github.event.inputs.parallelism || 2 }} run: | - count=${{ github.event.inputs.parallelism || 2 }} - matrix=$(seq -s ',' 1 $count) - echo "matrix=$(jq -cn --argjson groups "[$matrix]" '{group: $groups}')" >> $GITHUB_OUTPUT + count="${PARALLELISM:-2}" + if ! [[ "$count" =~ ^[1-9][0-9]*$ ]]; then + echo "parallelism must be a positive integer" >&2 + exit 1 + fi + groups=$(seq 1 "$count" | jq -Rsc 'split("\n")[:-1] | map(tonumber)') + matrix_json=$(jq -cn --argjson groups "$groups" '{group: $groups}') + echo "matrix=$matrix_json" >> "$GITHUB_OUTPUT" monthly-test: needs: setup-matrix runs-on: ubuntu-latest @@ -55,17 +62,20 @@ jobs: uses: astral-sh/setup-uv@v8.2.0 with: enable-cache: true - - name: Create venv & install dependencies - run: | - uv venv - uv sync --all-extras --dev + - name: Install dependencies + run: uv sync --locked --all-extras --dev - name: Run Tests + env: + BASE_URL: ${{ vars.BASE_URL }} + GROUP: ${{ matrix.group }} + PARALLELISM: ${{ github.event.inputs.parallelism || 2 }} + PYTEST_MARKER: ${{ github.event.inputs.pytest_marker || 'not devRun' }} run: > - xvfb-run .venv/bin/python -m pytest - ${{ github.event.inputs.pytest_command || '-m "not devRun"' }} - --base-url ${{ vars.BASE_URL }} - --splits ${{ github.event.inputs.parallelism || 2 }} - --group ${{ matrix.group }} + xvfb-run uv run pytest + -m "$PYTEST_MARKER" + --base-url "$BASE_URL" + --splits "$PARALLELISM" + --group "$GROUP" - name: Upload shard allure-results if: always() uses: actions/upload-artifact@v7 @@ -91,15 +101,19 @@ jobs: - name: Link Git Information And Browser Version To Allure Results if: always() working-directory: allure-results + env: + BUILD_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GIT_BRANCH: ${{ github.ref_name }} + GIT_COMMIT_ID: ${{ github.sha }} run: | { - echo BUILD_URL=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - echo GIT_BRANCH=${{ github.ref_name }} - echo GIT_COMMIT_ID=${{ github.sha }} - echo GIT_COMMIT_MESSAGE="$(git show -s --format=%s HEAD)" - echo GIT_COMMIT_AUTHOR_NAME="$(git show -s --format='%ae' HEAD)" - echo GIT_COMMIT_TIME="$(git show -s --format=%ci HEAD)" - echo CHROME_VERSION="$(google-chrome --product-version 2>/dev/null || true)" + printf 'BUILD_URL=%s\n' "$BUILD_URL" + printf 'GIT_BRANCH=%s\n' "$GIT_BRANCH" + printf 'GIT_COMMIT_ID=%s\n' "$GIT_COMMIT_ID" + printf 'GIT_COMMIT_MESSAGE=%s\n' "$(git show -s --format=%s HEAD)" + printf 'GIT_COMMIT_AUTHOR_NAME=%s\n' "$(git show -s --format='%ae' HEAD)" + printf 'GIT_COMMIT_TIME=%s\n' "$(git show -s --format=%ci HEAD)" + printf 'CHROME_VERSION=%s\n' "$(google-chrome --product-version 2>/dev/null || true)" } >> environment.properties - name: Generate Allure HTML report if: always() diff --git a/.github/workflows/devRun.yml b/.github/workflows/pr.yml similarity index 63% rename from .github/workflows/devRun.yml rename to .github/workflows/pr.yml index ed22597663..ba4aee62c5 100644 --- a/.github/workflows/devRun.yml +++ b/.github/workflows/pr.yml @@ -1,4 +1,4 @@ -name: Pre merge test +name: Pull Request Tests on: pull_request: @@ -7,7 +7,7 @@ on: - "**/*.py" - "**/*.toml" - "**/*.lock" - - ".github/workflows/devRun.yml" + - ".github/workflows/pr.yml" env: FLAKINESS_PROJECT: nirtal85/Selenium-Python-Example @@ -33,30 +33,37 @@ jobs: uses: astral-sh/setup-uv@v8.2.0 with: enable-cache: true - - name: Create venv & install dependencies - run: | - uv venv - uv sync --all-extras --dev + - name: Install dependencies + run: uv sync --locked --all-extras --dev + - name: Ruff check + run: uv run ruff check . + - name: Ruff format check + run: uv run ruff format --check . - name: Test with pytest env: EMAIL: ${{ secrets.EMAIL }} PASSWORD: ${{ secrets.PASSWORD }} - run: xvfb-run .venv/bin/python -m pytest -m devRun --base-url ${{ vars.BASE_URL }} + BASE_URL: ${{ vars.BASE_URL }} + run: xvfb-run uv run pytest -m devRun --base-url "$BASE_URL" - name: Auto-assign reviewers uses: kentaro-m/auto-assign-action@v2.0.2 if: success() - name: Link Git Information And Browser Version To Allure Results if: always() working-directory: allure-results + env: + BUILD_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GIT_BRANCH: ${{ github.head_ref || github.ref_name }} + GIT_COMMIT_ID: ${{ github.sha }} run: | { - echo BUILD_URL=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - echo GIT_BRANCH=${{ github.head_ref || github.ref_name }} - echo GIT_COMMIT_ID=${{ github.sha }} - echo GIT_COMMIT_MESSAGE="$(git show -s --format=%s HEAD)" - echo GIT_COMMIT_AUTHOR_NAME="$(git show -s --format='%ae' HEAD)" - echo GIT_COMMIT_TIME="$(git show -s --format=%ci HEAD)" - echo CHROME_VERSION="$(google-chrome --product-version 2>/dev/null || true)" + printf 'BUILD_URL=%s\n' "$BUILD_URL" + printf 'GIT_BRANCH=%s\n' "$GIT_BRANCH" + printf 'GIT_COMMIT_ID=%s\n' "$GIT_COMMIT_ID" + printf 'GIT_COMMIT_MESSAGE=%s\n' "$(git show -s --format=%s HEAD)" + printf 'GIT_COMMIT_AUTHOR_NAME=%s\n' "$(git show -s --format='%ae' HEAD)" + printf 'GIT_COMMIT_TIME=%s\n' "$(git show -s --format=%ci HEAD)" + printf 'CHROME_VERSION=%s\n' "$(google-chrome --product-version 2>/dev/null || true)" } >> environment.properties - name: Generate Allure HTML report (Allure 3 CLI via npx) if: always() diff --git a/README.md b/README.md index 14c2689b80..9bd857cf49 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [](https://twitter.com/NirTal2) [](https://www.youtube.com/channel/UCQjS-eoKl0a1nuP_dvpLsjQ) [](https://www.test-shift.com/) - +  [](https://flakiness.io/nirtal85/Selenium-Python-Example) [](https://github.com/astral-sh/uv) @@ -90,7 +90,7 @@ Windows: ```bash pip install uv uv venv -.\env\Scripts\activate +.\.venv\Scripts\activate uv sync --all-extras --dev ``` @@ -117,19 +117,19 @@ PASSWORD="your_secret_password" Run all tests (Headless Chrome by default): ```bash -pytest +uv run pytest ``` Run with specific browser: ```bash -pytest --driver firefox +uv run pytest --driver firefox ``` Run specific suite (Tags): ```bash -pytest -m sanity +uv run pytest -m sanity ``` ## 📊 Results & Reporting diff --git a/pyproject.toml b/pyproject.toml index b18cadcbce..310e512f07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,9 @@ dev = [ name = "selenium-python-example" description = "Selenium Python example project with pytest and Allure report" version = "0.1.0" +readme = "README.md" +license = "MIT" +authors = [{ name = "Nir Tal" }] dependencies = [ "allure-pytest==2.16.0", "assertpy==1.1", @@ -51,7 +54,10 @@ addopts = [ base_url = 'https://www.involve.me/' markers = [ "security: marks security tests", - "devRun: marks tests that run before merge to the main branch" + "devRun: marks tests that run before merge to the main branch", + "flaky: marks tests that may be rerun", + "run: marks ordered test execution", + "sanity: marks sanity tests" ] testpaths = [ "tests" @@ -59,14 +65,16 @@ testpaths = [ [tool.ruff] exclude = [".venv", "env"] +line-length = 100 +target-version = "py311" + +[tool.ruff.lint] ignore = [ "D203", # One blank line required before class docstring (conflicts with D211) "D213", # Multi-line docstring summary should start at the second line "COM812" ] -line-length = 100 -select = ["ALL"] -target-version = "py311" +select = ["E", "F", "B", "I", "UP", "SIM", "PT"] [tool.ruff.format] docstring-code-format = true diff --git a/src/pages/base_page.py b/src/pages/base_page.py index b41078ae3a..299d4350e4 100644 --- a/src/pages/base_page.py +++ b/src/pages/base_page.py @@ -46,7 +46,8 @@ def set_geo_location(self, latitude: float, longitude: float) -> None: Note: This method uses the Chrome DevTools Protocol (CDP) to override the geolocation - in the web browser, allowing simulation of a specific geographic location for testing purposes. + in the web browser, allowing simulation of a specific geographic location for + testing purposes. The accuracy is set to 1 for simplicity in this method. """ @@ -99,15 +100,21 @@ def is_elem_displayed(self, webelement: WebElement) -> bool: def _highlight_element(self, webelement: WebElement, color: str) -> None: original_style = webelement.get_attribute("style") new_style = f"background-color:yellow;border: 1px solid {color}{original_style}" + set_style_script = ( + "var tmpArguments = arguments;" + "setTimeout(function () {" + "tmpArguments[0].setAttribute('style', tmpArguments[1]);" + "}, tmpArguments[2]);" + ) self.driver.execute_script( - "var tmpArguments = arguments;setTimeout(function () {tmpArguments[0].setAttribute('style', '" - + new_style - + "');},0);", + set_style_script, webelement, + new_style, + 0, ) self.driver.execute_script( - "var tmpArguments = arguments;setTimeout(function () {tmpArguments[0].setAttribute('style', '" - + original_style - + "');},400);", + set_style_script, webelement, + original_style, + 400, ) diff --git a/src/utilities/excel_parser.py b/src/utilities/excel_parser.py index f32a709447..663d9aa8d8 100644 --- a/src/utilities/excel_parser.py +++ b/src/utilities/excel_parser.py @@ -19,7 +19,7 @@ def read_from_excel(self, sheet_name): num_cols = sheet.ncols # Number of columns for row_idx, col_idx in itertools.product(range(1, sheet.nrows), range(num_cols)): cell_obj = sheet.cell(row_idx, col_idx) # Get cell object by row, col - # Convert cell to string,split it according to "'" and take the second cell in the array created - # e.g.: cell_obj == "text:'something'" --> after convert and splitting == "something" + # Convert cell to string, split on "'" and take the value segment. + # e.g.: cell_obj == "text:'something'" --> "something" rows_val.append(str(cell_obj).split("'")[1]) return rows_val diff --git a/src/utilities/mailinator_helper.py b/src/utilities/mailinator_helper.py index 2a8ccc4e0b..63552f34fa 100644 --- a/src/utilities/mailinator_helper.py +++ b/src/utilities/mailinator_helper.py @@ -55,8 +55,8 @@ def __get_message_id(self, user_email: str, email_subject: str) -> str: email_subject (str): The subject of the email to wait for. Returns: - str or None: The message ID of the email with the specified subject, or None if the email - is not found within the inbox. + str or None: The message ID of the email with the specified subject, or + None if the email is not found within the inbox. Raises: Any exceptions raised by the underlying `self.mailinator.request` method when @@ -66,13 +66,13 @@ def __get_message_id(self, user_email: str, email_subject: str) -> str: messages = self.mailinator.request( GetInboxRequest( domain=self.mailinator_domain, - inbox=user_email.split("@")[0], + inbox=user_email.split("@", maxsplit=1)[0], ) ).msgs filtered_messages: list[Message] = [ message for message in messages - if message.to == user_email.split("@")[0] + if message.to == user_email.split("@", maxsplit=1)[0] and message.subject.casefold() == email_subject.casefold() ] return filtered_messages[0].id if filtered_messages else None @@ -160,7 +160,7 @@ def count_messages_by_subject(self, user_email: str) -> dict[str, int]: messages = self.mailinator.request( GetInboxRequest( domain=self.mailinator_domain, - inbox=user_email.split("@")[0], + inbox=user_email.split("@", maxsplit=1)[0], ) ).msgs # Use a list comprehension to extract the subjects from each message diff --git a/src/utilities/vrt_helper.py b/src/utilities/vrt_helper.py index 898bbe958c..f3bb8ccb8b 100644 --- a/src/utilities/vrt_helper.py +++ b/src/utilities/vrt_helper.py @@ -57,7 +57,9 @@ def shoot_page(self, baseline_name: str) -> None: TestRunStatus.OK.name, ) - def shoot_page_ang_ignore_elements(self, baseline_name: str, elements: list[WebElement]) -> None: + def shoot_page_ang_ignore_elements( + self, baseline_name: str, elements: list[WebElement] + ) -> None: """Capture a screenshot of the current page, define areas to be ignored within the screenshot, compare the captured screenshot with a baseline image stored in Visual Regression tracker. diff --git a/tests/conftest.py b/tests/conftest.py index dddb42b94f..d5f227a2a3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,13 +28,16 @@ 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.excel_parser import ExcelParser +from src.utilities.mailinator_helper import MailinatorHelper from src.utilities.vrt_helper import VrtHelper +from src.utilities.web_driver_listener import DriverEventListener -drivers = ("chrome", "firefox", "chrome_headless", "remote") +drivers = ("chrome", "firefox", "chrome_headless") +DEFAULT_WINDOW_WIDTH = 1920 +DEFAULT_WINDOW_HEIGHT = 1080 +CHROME_BROWSER_VERSION = "150.0.7871.114" def pytest_addoption(parser: Parser) -> None: @@ -158,8 +161,7 @@ def pytest_runtest_setup(item: Item) -> None: }, ) chrome_options.enable_bidi = True - # https://forum.robotframework.org/t/maximize-window-chromedriver-133/8416/3 - chrome_options.browser_version = "132" + chrome_options.browser_version = CHROME_BROWSER_VERSION chrome_options.add_argument("disable-dev-shm-usage") chrome_options.add_argument("no-sandbox") chrome_options.add_argument("allow-file-access-from-files") @@ -189,24 +191,10 @@ def pytest_runtest_setup(item: Item) -> None: case "chrome_headless": chrome_options.add_argument("headless=new") chrome_options.add_argument("force-device-scale-factor=0.6") - chrome_options.add_argument("window-size=1920,1080") - driver = webdriver.Chrome(options=chrome_options) - # https://stackoverflow.com/questions/76430192/getting-typeerror-webdriver-init-got-an-unexpected-keyword-argument-desi - case "remote": - chrome_options = webdriver.ChromeOptions() - # https://aerokube.com/images/latest/#_chrome - chrome_options.browser_version = "128.0" - chrome_options.set_capability( - "selenoid:options", - { - "enableVNC": True, - "enableVideo": True, - "videoName": f"{item.name}.mp4", - }, - ) - driver = webdriver.Remote( - command_executor="http://localhost:4444/wd/hub", options=chrome_options + chrome_options.add_argument( + f"window-size={DEFAULT_WINDOW_WIDTH},{DEFAULT_WINDOW_HEIGHT}" ) + driver = webdriver.Chrome(options=chrome_options) case _: if item.config.getoption("decorate_driver"): driver = EventFiringWebDriver( @@ -215,18 +203,17 @@ def pytest_runtest_setup(item: Item) -> None: else: driver = webdriver.Chrome(options=chrome_options) item.cls.driver = driver - driver.maximize_window() + driver.set_window_size(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT) driver.get(base_url) wait = WebDriverWait(driver, 10) - if browser != "remote": - console_messages = [] - driver.script.add_console_message_handler( - lambda log_entry: console_messages.append(log_entry.__dict__) - ) - javascript_errors = [] - driver.script.add_javascript_error_handler( - lambda log_entry: javascript_errors.append(log_entry.__dict__) - ) + console_messages = [] + driver.script.add_console_message_handler( + lambda log_entry: console_messages.append(log_entry.__dict__) + ) + javascript_errors = [] + driver.script.add_javascript_error_handler( + lambda log_entry: javascript_errors.append(log_entry.__dict__) + ) item.cls.wait = wait item.cls.about_page = AboutPage(driver, wait) item.cls.login_page = LoginPage(driver, wait) @@ -268,9 +255,9 @@ def pytest_sessionstart() -> None: def pytest_exception_interact(node: Item) -> None: """Pytest hook for interacting with exceptions during test execution. - If the 'driver' variable is present in the local or global namespace, this function performs various - actions for reporting using the 'allure' reporting framework. If 'driver' is not present, the function - returns without taking any action. + If the 'driver' variable is present, this function performs reporting actions + using the 'allure' reporting framework. If 'driver' is not present, the + function returns without taking any action. Args: node (Item): The pytest Item representing the test item. @@ -283,38 +270,6 @@ def pytest_exception_interact(node: Item) -> None: if "driver" not in locals() and "driver" not in globals(): return window_count = len(driver.window_handles) - if browser == "remote": - allure.attach( - body="
", - name="Video record", - attachment_type=allure.attachment_type.HTML, - ) - if window_count == 1: - allure.attach( - body=driver.get_screenshot_as_png(), - name="Full Page Screenshot", - attachment_type=allure.attachment_type.PNG, - ) - allure.attach( - body=driver.current_url, - name="URL", - attachment_type=allure.attachment_type.URI_LIST, - ) - else: - for window in range(window_count): - driver.switch_to.window(driver.window_handles[window]) - allure.attach( - body=driver.get_screenshot_as_png(), - name=f"Full Page Screen Shot of window in index {window}", - attachment_type=allure.attachment_type.PNG, - ) - allure.attach( - body=driver.current_url, - name=f"URL of window in index {window}", - attachment_type=allure.attachment_type.URI_LIST, - ) with allure.step("public ip address"): get_public_ip(session_request) allure.attach( @@ -345,50 +300,48 @@ def pytest_exception_interact(node: Item) -> None: attachment_type=allure.attachment_type.JSON, ) - if browser != "remote": - # https://github.com/lana-20/selenium-webdriver-bidi - if console_messages: - allure.attach( - body=json.dumps(console_messages, indent=4), - name="Console Logs", - attachment_type=allure.attachment_type.JSON, - ) - if javascript_errors: - allure.attach( - body=json.dumps(javascript_errors, indent=4), - name="JavaScript Errors", - attachment_type=allure.attachment_type.JSON, - ) - # looks like cdp not working with remote: https://github.com/SeleniumHQ/selenium/issues/8672 - if window_count == 1: + # https://github.com/lana-20/selenium-webdriver-bidi + if console_messages: + allure.attach( + body=json.dumps(console_messages, indent=4), + name="Console Logs", + attachment_type=allure.attachment_type.JSON, + ) + if javascript_errors: + allure.attach( + body=json.dumps(javascript_errors, indent=4), + name="JavaScript Errors", + attachment_type=allure.attachment_type.JSON, + ) + if window_count == 1: + allure.attach( + body=capture_full_page_screenshot(), + name="Full Page Screenshot", + attachment_type=allure.attachment_type.PNG, + ) + allure.attach( + body=driver.current_url, + name="URL", + attachment_type=allure.attachment_type.URI_LIST, + ) + else: + for window in range(window_count): + driver.switch_to.window(driver.window_handles[window]) allure.attach( body=capture_full_page_screenshot(), - name="Full Page Screenshot", + name=f"Full Page Screen Shot of window in index {window}", attachment_type=allure.attachment_type.PNG, ) allure.attach( body=driver.current_url, - name="URL", + name=f"URL of window in index {window}", attachment_type=allure.attachment_type.URI_LIST, ) - else: - for window in range(window_count): - driver.switch_to.window(driver.window_handles[window]) - allure.attach( - body=capture_full_page_screenshot(), - name=f"Full Page Screen Shot of window in index {window}", - attachment_type=allure.attachment_type.PNG, - ) - allure.attach( - body=driver.current_url, - name=f"URL of window in index {window}", - attachment_type=allure.attachment_type.URI_LIST, - ) - allure.attach( - body=json.dumps(attach_network_logs(), indent=4), - name="Network Logs", - attachment_type=allure.attachment_type.JSON, - ) + allure.attach( + body=json.dumps(attach_network_logs(), indent=4), + name="Network Logs", + attachment_type=allure.attachment_type.JSON, + ) def get_response_body(request_id): diff --git a/tests/dependency_class_test.py b/tests/dependency_class_test.py index a3cd60845c..ae726c9c8b 100644 --- a/tests/dependency_class_test.py +++ b/tests/dependency_class_test.py @@ -11,7 +11,7 @@ class TestDependencyExample(BaseTest): """ def test_e(self) -> None: - """Placeholder test function with the dependency name "e" and depends on "TestDependencyExample::b". + """Placeholder with dependency name "e" and depends on "TestDependencyExample::b". This test case is designed for demonstration purposes only. """ diff --git a/tests/dependency_test.py b/tests/dependency_test.py index 5cc975318d..f23644b6e0 100644 --- a/tests/dependency_test.py +++ b/tests/dependency_test.py @@ -23,7 +23,7 @@ def test_a(self) -> None: @pytest.mark.dependency(name="b") def test_b(self) -> None: - assert False + pytest.fail("Dependency example failure") @pytest.mark.dependency(name="c", depends=["b"]) def test_c(self) -> None: diff --git a/tests/email_test.py b/tests/email_test.py index 791fe4b4b5..ffe1e6b8c3 100644 --- a/tests/email_test.py +++ b/tests/email_test.py @@ -1,5 +1,3 @@ -from unittest import TestCase - import allure import pytest @@ -11,7 +9,7 @@ class TestEmail(BaseTest): @allure.title("Verify email count in user inbox") 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) + assert subject_counts == {"some subject": 1} @allure.title("Verify email content") def test_verify_email_body(self, mailinator_helper) -> None: diff --git a/tests/login_test.py b/tests/login_test.py index cd2ecfa466..52b800c373 100644 --- a/tests/login_test.py +++ b/tests/login_test.py @@ -6,9 +6,9 @@ import pytest from assertpy import assert_that -from tests.base_test import BaseTest from src.utilities.constants import Constants from src.utilities.data import Data +from tests.base_test import BaseTest users = [("nirt236@gmail.com", "123456"), ("elias@gmail.com", "12345Tr")] @@ -20,7 +20,7 @@ class TestLogin(BaseTest): @allure.description("invalid login") @allure.title("Login with invalid credentials test") - @pytest.mark.parametrize("email, password", users) + @pytest.mark.parametrize(("email", "password"), users) @pytest.mark.run(order=3) def test_invalid_login(self, email: str, password: str, data: Data) -> None: self.about_page.click_login_link() @@ -31,6 +31,7 @@ def test_invalid_login(self, email: str, password: str, data: Data) -> None: @allure.description("Basic sanity") @pytest.mark.devRun + @pytest.mark.sanity def test_sanity(self, base_url) -> None: assert_that(self.driver.current_url).described_as("URL").is_equal_to(base_url) diff --git a/tests/workspaces_test.py b/tests/workspaces_test.py index 42bbe31980..4ea29fdd3a 100644 --- a/tests/workspaces_test.py +++ b/tests/workspaces_test.py @@ -52,7 +52,8 @@ def test_delete_workspace(self) -> None: assert_that(after).described_as("workspace number").is_less_than(before) @allure.description( - "Compare between the actual number of projects seen on page and the number shown in workspaces block" + "Compare between the actual number of projects seen on page and the number " + "shown in workspaces block" ) @allure.title("Number of projects displayed in page test") @pytest.mark.run(order=4) @@ -113,6 +114,4 @@ def test_delete_project(self, data: Data) -> None: before = self.projects_page.get_projects_number_in_page() self.projects_page.delete_project(data.workspace.project_name) after = self.projects_page.get_projects_number_in_page() - assert_that(before).described_as("number of displayed projects").is_equal_to( - after + 1 - ) + assert_that(before).described_as("number of displayed projects").is_equal_to(after + 1)