From f69cb2ef541e7b6d29a05aea6a7fd86388b68705 Mon Sep 17 00:00:00 2001 From: Igor Date: Tue, 24 Jun 2025 23:54:38 +0900 Subject: [PATCH 01/23] add API GET-method --- tests/api/steps/jenkins_steps.py | 20 ++++++++++++++++++++ tests/api/support/jenkins_client.py | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/api/steps/jenkins_steps.py b/tests/api/steps/jenkins_steps.py index 9bdabe12c..5add3653a 100644 --- a/tests/api/steps/jenkins_steps.py +++ b/tests/api/steps/jenkins_steps.py @@ -40,3 +40,23 @@ def post_create_item_in_folder(self, folder_name: str, project_name: str, config f"Endpoint: {endpoint}\n" f"Status: {getattr(response, 'status_code', 'N/A')}" ) + + @allure.step("GET /job/{project_name}/api/json") + def get_job_config_json(self, project_name: str, params: dict = None) -> dict: + endpoint = f"job/{project_name}/api/json" + query_params = {"pretty": "true", **(params or {})} + response = self.client.get(endpoint, params=query_params) + + if response and response.ok: + allure.attach(response.text, name="JSON data", attachment_type=allure.attachment_type.JSON) + return response.json() + + else: + msg = response.text if response else "No response" + allure.attach(msg, name=f"[Failed]{project_name}", attachment_type=allure.attachment_type.TEXT) + raise RuntimeError( + f"Failed to get config for job '{project_name}'.\n" + f"Endpoint: /{endpoint}\n" + f"Params: {params}\n" + f"Status: {response.status_code} - {response.reason}" + ) diff --git a/tests/api/support/jenkins_client.py b/tests/api/support/jenkins_client.py index 3284b445a..9386d9bb1 100644 --- a/tests/api/support/jenkins_client.py +++ b/tests/api/support/jenkins_client.py @@ -27,3 +27,11 @@ def post_xml(self, endpoint: str, xml_data: str): return response return response + + def get(self, endpoint: str, params: dict = None) -> requests.Response: + headers = {'Content-Type': 'application/json'} + headers.update(self.crumb_headers) + url = f"{self.BASE_URL}/{endpoint}" + response = self.session.get(url, headers=headers, params=params) + logger.info(f"[GET] /{endpoint} - Status: {response.status_code} - {response.reason}") + return response From 2238532198779c31df7926ba1dea736cb297ec20 Mon Sep 17 00:00:00 2001 From: Igor Date: Tue, 24 Jun 2025 23:55:22 +0900 Subject: [PATCH 02/23] add test --- tests/api/tests_ui/freestyle/conftest.py | 10 ++++++++++ .../tests_ui/freestyle/test_build_triggers.py | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/api/tests_ui/freestyle/conftest.py b/tests/api/tests_ui/freestyle/conftest.py index 31bf29738..e9c5acad2 100644 --- a/tests/api/tests_ui/freestyle/conftest.py +++ b/tests/api/tests_ui/freestyle/conftest.py @@ -67,3 +67,13 @@ def create_empty_job_with_api() -> Dict[str, Any]: "token": token, "crumb_headers": crumb_headers } + + +@pytest.fixture(scope="function") +def create_freestyle_scheduled_project_by_xml_via_api(jenkins_steps, main_page): + project_name, timer, timeout, config_xml = Data.get_freestyle_scheduled_every_minute_data() + jenkins_steps.post_create_item(project_name, config_xml) + main_page.driver.refresh() + main_page.go_to_freestyle_project_page(project_name).wait_for_build_execution(timeout) + json_data = jenkins_steps.get_job_config_json(project_name) + return project_name, json_data diff --git a/tests/api/tests_ui/freestyle/test_build_triggers.py b/tests/api/tests_ui/freestyle/test_build_triggers.py index 6b24362f1..687f02a8d 100644 --- a/tests/api/tests_ui/freestyle/test_build_triggers.py +++ b/tests/api/tests_ui/freestyle/test_build_triggers.py @@ -9,7 +9,6 @@ "and that the build runs according to the specified schedule.") @allure.testcase("https://github.com/RedRoverSchool/JenkinsQA_Python_2025_spring/issues/643", "TC_02.004.002") @allure.link("https://github.com/RedRoverSchool/JenkinsQA_Python_2025_spring/issues/643", name="Github issue") -@pytest.mark.xfail(reason="May fail due to non-reproducible concurrent builds locally.") def test_user_can_trigger_build_periodically(create_freestyle_project_scheduled_every_minute_by_api, main_page): project_name, timeout = create_freestyle_project_scheduled_every_minute_by_api @@ -26,3 +25,20 @@ def test_user_can_trigger_build_periodically(create_freestyle_project_scheduled_ assert builds[0].split("\n")[0] == project_name, f"No build entry found for '{project_name}'" with allure.step("Assert that the build has number \"#1\"."): assert builds[0].split("\n")[1] == "#1", "Build #1 not found." + + +def test_freestyle_project_ui_fields_match_api_json(create_freestyle_scheduled_project_by_xml_via_api, main_page): + project_name, json_data = create_freestyle_scheduled_project_by_xml_via_api + page = main_page.go_to_freestyle_project_page(project_name) + assert project_name in json_data.get("url") + assert page.get_h1_value() == json_data.get("displayName") + assert page.get_description() == json_data.get("description") + + builds_ui = page.header.go_to_the_main_page() \ + .go_to_build_history_page() \ + .get_builds_list() + + first_build_ui_number = builds_ui[0].split("\n")[1] + first_build_json_number = f"#{json_data['builds'][0]['number']}" + + assert first_build_ui_number == first_build_json_number == "#1" From 1833918f3edeb5ea27b66cdc0d760e1aa80b0d99 Mon Sep 17 00:00:00 2001 From: Igor Date: Tue, 24 Jun 2025 23:58:35 +0900 Subject: [PATCH 03/23] changed method to use a stable locator --- pages/freestyle_project_page.py | 9 +++++++-- pages/main_page.py | 5 ++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index eab97f6ef..8e2cce2fc 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -1,3 +1,5 @@ +import time + import allure import logging @@ -67,10 +69,13 @@ def get_menu_items_texts(self): @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") def wait_for_build_execution(self, timeout): with allure.step("Wait for 'Builds' link to be visible"): + start = time.time() build_link = self.wait_for_element(self.Locators.BUILDS_LINK, timeout) + elapsed = round(time.time() - start, 2) + if not build_link: - logger.error(f"'Builds' link was not found within {timeout} seconds.") + logger.error(f"'Builds' link was not found within {timeout} seconds. Waited: {elapsed} seconds.") else: - logger.info(f"'Builds' link appeared within {timeout} seconds.") + logger.info(f"'Builds' link appeared in {elapsed} seconds.") return self diff --git a/pages/main_page.py b/pages/main_page.py index fb1a9ceec..3b993f9e4 100644 --- a/pages/main_page.py +++ b/pages/main_page.py @@ -94,10 +94,9 @@ def go_to_the_folder_page(self, name): return self.navigate_to(FolderPage, self.Locators.table_item_link(name), name) @allure.step("Go to the Freestyle project page by clicking project link.") - def go_to_freestyle_project_page(self, project_name): + def go_to_freestyle_project_page(self, name): from pages.freestyle_project_page import FreestyleProjectPage - self.wait_to_be_clickable(self.Locators.PROJECT_BUTTON).click() - return FreestyleProjectPage(self.driver, project_name).wait_for_url() + return self.navigate_to(FreestyleProjectPage, self.Locators.table_item_link(name), name) @allure.step("Expand build queue info block if it is collapsed.") def show_build_queue_info_block(self): From 9713d5e08311499c63eb6cf50ef1b4bef164aff8 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 25 Jun 2025 00:06:32 +0900 Subject: [PATCH 04/23] remove unused import --- tests/api/tests_ui/freestyle/test_build_triggers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/api/tests_ui/freestyle/test_build_triggers.py b/tests/api/tests_ui/freestyle/test_build_triggers.py index 687f02a8d..3c052b414 100644 --- a/tests/api/tests_ui/freestyle/test_build_triggers.py +++ b/tests/api/tests_ui/freestyle/test_build_triggers.py @@ -1,5 +1,4 @@ import allure -import pytest @allure.epic("Freestyle Project Configuration") From 89af23435aef22d3a36e57b3667a402d761a0424 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 25 Jun 2025 01:36:23 +0900 Subject: [PATCH 05/23] ref config --- tests/api/tests_ui/freestyle/data.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index 6a1ab754d..015e247ff 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -31,10 +31,11 @@ def get_freestyle_scheduled_xml(cls, description: str, timer: str) -> str: false false - - {timer} - + + {timer} + + 10 false From 96f650d678196ef1261eb1ce7f66fd92016d3d32 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 25 Jun 2025 05:05:08 +0900 Subject: [PATCH 06/23] ref config --- tests/api/tests_ui/freestyle/data.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index 015e247ff..4cb9906fa 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -35,9 +35,13 @@ def get_freestyle_scheduled_xml(cls, description: str, timer: str) -> str: {timer} - 10 false - + + + sleep 35 + + + From 43843dd80618bf1ab342117a07cafe551c1a1a35 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 25 Jun 2025 05:22:24 +0900 Subject: [PATCH 07/23] add builds_list_screenshot --- tests/api/tests_ui/freestyle/test_build_triggers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/api/tests_ui/freestyle/test_build_triggers.py b/tests/api/tests_ui/freestyle/test_build_triggers.py index 3c052b414..f1982c9d6 100644 --- a/tests/api/tests_ui/freestyle/test_build_triggers.py +++ b/tests/api/tests_ui/freestyle/test_build_triggers.py @@ -18,6 +18,9 @@ def test_user_can_trigger_build_periodically(create_freestyle_project_scheduled_ .go_to_build_history_page()\ .get_builds_list() + with allure.step("Attach screenshot before asserting number of builds."): + screenshot = main_page.driver.get_screenshot_as_png() + allure.attach(screenshot, name="builds_list_screenshot", attachment_type=allure.attachment_type.PNG) with allure.step("Assert that only one build is displayed in the list."): assert len(builds) == 1, f"Expected 1 build, found {len(builds)}" with allure.step(f"Assert that the project name of the displayed build is \"{project_name}\"."): From 395e1a95192ae3fd9fba242cc17a759b5a527a2e Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 15:22:50 +0900 Subject: [PATCH 08/23] fix config xml trigger --- tests/api/tests_ui/freestyle/data.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index 6a1ab754d..5e9326ae8 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -36,7 +36,13 @@ def get_freestyle_scheduled_xml(cls, description: str, timer: str) -> str: false - + + + echo ID=$(date +%s | cut -c1-2) + sleep 35 + + + From e638dd3b83c87c1ef172ec7432bcb4e012d94388 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 15:32:08 +0900 Subject: [PATCH 09/23] fix config xml trigger --- .github/workflows/continuous_integration.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 9b8edddf4..af3ecd8e0 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -1,6 +1,9 @@ name: Run the tests on pull requests on: + push: + branches: + - main pull_request: branches: - main From 9ed05d7cbe17697f65389595de8168f57d0e3588 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 16:46:24 +0900 Subject: [PATCH 10/23] Run tests from tests/api/tests_ui only --- .github/workflows/continuous_integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index af3ecd8e0..3288442b2 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -72,8 +72,8 @@ jobs: - name: Wait for the Jenkins run: ./.github/wait-for-jenkins.sh - - name: pytest run all tests - run: pytest --alluredir=build/allure-results + - name: Run tests from tests/api/tests_ui only + run: pytest tests/api/tests_ui --alluredir=build/allure-results - name: Get Allure history uses: actions/checkout@v4.2.2 From df9e4cf661422af73a208bbfac0b61ab42d75726 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 17:06:47 +0900 Subject: [PATCH 11/23] Run tests from tests/api/tests_ui only --- .github/workflows/continuous_integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 9b8edddf4..ffe126b03 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -69,8 +69,8 @@ jobs: - name: Wait for the Jenkins run: ./.github/wait-for-jenkins.sh - - name: pytest run all tests - run: pytest --alluredir=build/allure-results + - name: Run tests from tests/api/tests_ui only + run: pytest tests/api/tests_ui --alluredir=build/allure-results - name: Get Allure history uses: actions/checkout@v4.2.2 From 7f1341fe7beebddc9981d89f9c3a123f45a83e81 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 17:41:46 +0900 Subject: [PATCH 12/23] Run tests from tests/api/tests_ui only --- .github/workflows/continuous_integration.yml | 7 +++++-- tests/api/tests_ui/freestyle/data.py | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 3288442b2..053b35c70 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -72,8 +72,11 @@ jobs: - name: Wait for the Jenkins run: ./.github/wait-for-jenkins.sh - - name: Run tests from tests/api/tests_ui only - run: pytest tests/api/tests_ui --alluredir=build/allure-results +# - name: Run tests from tests/api/tests_ui/frees only +# run: pytest tests/api/tests_ui --alluredir=build/allure-results + + - name: Run one test 10 times + run: pytest tests/api/tests_ui/freestyle/test_build_triggers.py --count=10 - name: Get Allure history uses: actions/checkout@v4.2.2 diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index b09f6e522..523f1a0ad 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -38,8 +38,8 @@ def get_freestyle_scheduled_xml(cls, description: str, timer: str) -> str: false - echo ID=$(date +%s | cut -c1-2) - sleep 35 + + sleep 31 From 605cdcfe29a9e4ea3c4cc044b9a7039685840d1f Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 17:44:36 +0900 Subject: [PATCH 13/23] Run tests from tests/api/tests_ui only --- .github/workflows/continuous_integration.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 053b35c70..4286ffbd2 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -46,6 +46,9 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt + - name: Install pytest-repeat + run: pip install pytest-repeat + - name: Install the code linting and formatting tool Ruff run: pip install ruff From 35ac8336bf4b0a7cf96c5a41cff0b33f383135f1 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 21:15:15 +0900 Subject: [PATCH 14/23] Run tests from tests/api/tests_ui only --- .github/workflows/continuous_integration.yml | 2 +- tests/api/tests_ui/freestyle/data.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 4286ffbd2..5ab2fe228 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -79,7 +79,7 @@ jobs: # run: pytest tests/api/tests_ui --alluredir=build/allure-results - name: Run one test 10 times - run: pytest tests/api/tests_ui/freestyle/test_build_triggers.py --count=10 + run: pytest tests/api/tests_ui/freestyle/test_build_triggers.py --count=10 --alluredir=build/allure-results - name: Get Allure history uses: actions/checkout@v4.2.2 diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index 523f1a0ad..d343b686a 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -39,7 +39,7 @@ def get_freestyle_scheduled_xml(cls, description: str, timer: str) -> str: - sleep 31 + sleep 10 From 8a205e322bc20681c725ba799192b2fcb7a07156 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 22:39:07 +0900 Subject: [PATCH 15/23] Run tests from tests/api/tests_ui only --- .env.TEMPLATE | 7 ------ .github/workflows/continuous_integration.yml | 2 +- pages/freestyle_project_page.py | 25 +++++++++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) delete mode 100644 .env.TEMPLATE diff --git a/.env.TEMPLATE b/.env.TEMPLATE deleted file mode 100644 index 533952659..000000000 --- a/.env.TEMPLATE +++ /dev/null @@ -1,7 +0,0 @@ -JENKINS_USERNAME= -JENKINS_PASSWORD= -JENKINS_HOST=localhost -JENKINS_PORT=8080 -BROWSER_NAME=chrome -BROWSER_OPTIONS_CHROME=--window-size=1920,1080 -BROWSER_OPTIONS_EDGE=--window-size=1920,1080 \ No newline at end of file diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 5ab2fe228..6efcd54f6 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -79,7 +79,7 @@ jobs: # run: pytest tests/api/tests_ui --alluredir=build/allure-results - name: Run one test 10 times - run: pytest tests/api/tests_ui/freestyle/test_build_triggers.py --count=10 --alluredir=build/allure-results + run: pytest tests/api/tests_ui/freestyle/test_build_triggers.py --count=1 --alluredir=build/allure-results - name: Get Allure history uses: actions/checkout@v4.2.2 diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index 8e2cce2fc..2f26645a9 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -67,15 +67,24 @@ def get_menu_items_texts(self): return [item.text for item in self.wait_to_be_visible_all(self.Locators.MENU_ITEMS)] @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") - def wait_for_build_execution(self, timeout): - with allure.step("Wait for 'Builds' link to be visible"): + def wait_for_build_execution(self, timeout=60): + with allure.step(f"Wait up to {timeout} seconds for builds to appear"): start = time.time() - build_link = self.wait_for_element(self.Locators.BUILDS_LINK, timeout) - elapsed = round(time.time() - start, 2) + build_count = 0 + + while time.time() - start < timeout: + builds = self.find_elements(*self.Locators.BUILDS_LINK) # предполагаю, что это локатор всех билдов + current_count = len(builds) if builds else 0 + + if current_count > 0: + build_count = current_count + break + time.sleep(1) # подождать секунду и проверить снова - if not build_link: - logger.error(f"'Builds' link was not found within {timeout} seconds. Waited: {elapsed} seconds.") + elapsed = round(time.time() - start, 2) + if build_count == 0: + logger.error(f"No builds appeared within {timeout} seconds. Waited: {elapsed} seconds.") else: - logger.info(f"'Builds' link appeared in {elapsed} seconds.") + logger.info(f"{build_count} build(s) appeared in {elapsed} seconds.") - return self + return build_count, elapsed From d7ba2c7cf6bcfcdf146016a3f98d98872335cd1c Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 22:41:33 +0900 Subject: [PATCH 16/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index 2f26645a9..cb329efbe 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -87,4 +87,4 @@ def wait_for_build_execution(self, timeout=60): else: logger.info(f"{build_count} build(s) appeared in {elapsed} seconds.") - return build_count, elapsed + return self From 22fea3b7393577b8bf76d59cb5d04c9497c2788e Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 22:54:36 +0900 Subject: [PATCH 17/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index cb329efbe..218837d64 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -20,7 +20,7 @@ class Locators: CONFIGURE_MENU_ITEM = (By.LINK_TEXT, 'Configure') DESCRIPTION = (By.ID, 'description') MENU_ITEMS = (By.XPATH, '//div[@class="task "]') - BUILDS_LINK = (By.CSS_SELECTOR, "#jenkins-build-history>div>span~div a") + BUILDS_LINK = (By.CSS_SELECTOR, ".app-builds-container__item") def __init__(self, driver, project_name, timeout=5): super().__init__(driver, timeout=timeout) @@ -68,23 +68,18 @@ def get_menu_items_texts(self): @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") def wait_for_build_execution(self, timeout=60): - with allure.step(f"Wait up to {timeout} seconds for builds to appear"): + with allure.step("Wait for build(s) to appear in history"): start = time.time() - build_count = 0 + count = 0 - while time.time() - start < timeout: - builds = self.find_elements(*self.Locators.BUILDS_LINK) # предполагаю, что это локатор всех билдов - current_count = len(builds) if builds else 0 - - if current_count > 0: - build_count = current_count + for _ in range(timeout): + builds = self.find_elements(By.CSS_SELECTOR, ".app-builds-container__item") + visible = [b for b in builds if b.is_displayed()] + count = len(visible) + if count > 0: break - time.sleep(1) # подождать секунду и проверить снова + time.sleep(1) elapsed = round(time.time() - start, 2) - if build_count == 0: - logger.error(f"No builds appeared within {timeout} seconds. Waited: {elapsed} seconds.") - else: - logger.info(f"{build_count} build(s) appeared in {elapsed} seconds.") - - return self + logger.info(f"{count} build(s) appeared in {elapsed} seconds.") + return self From e6c49f7ae485d07cf1b5884ff09e971cc44e0751 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 23:04:25 +0900 Subject: [PATCH 18/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index 218837d64..22fd7400c 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -67,19 +67,11 @@ def get_menu_items_texts(self): return [item.text for item in self.wait_to_be_visible_all(self.Locators.MENU_ITEMS)] @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") - def wait_for_build_execution(self, timeout=60): - with allure.step("Wait for build(s) to appear in history"): - start = time.time() - count = 0 - - for _ in range(timeout): - builds = self.find_elements(By.CSS_SELECTOR, ".app-builds-container__item") - visible = [b for b in builds if b.is_displayed()] - count = len(visible) - if count > 0: - break - time.sleep(1) - - elapsed = round(time.time() - start, 2) - logger.info(f"{count} build(s) appeared in {elapsed} seconds.") - return self + def wait_and_count_builds(self): + logger.info("Waiting 60 seconds before counting builds...") + time.sleep(60) + + builds = self.find_elements(*self.Locators.BUILDS_LINK) + count = len(builds) + logger.info(f"{count} build(s) appeared after 60 seconds.") + return count From 35e9ebc3f424408068925d5d5c62b54f2b2f9402 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 23:04:39 +0900 Subject: [PATCH 19/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index 22fd7400c..896ded7fd 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -74,4 +74,4 @@ def wait_and_count_builds(self): builds = self.find_elements(*self.Locators.BUILDS_LINK) count = len(builds) logger.info(f"{count} build(s) appeared after 60 seconds.") - return count + return self From df0f034deec67d1d4f63badb4927dad704808f4e Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 23:09:32 +0900 Subject: [PATCH 20/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index 896ded7fd..3791766c4 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -67,7 +67,7 @@ def get_menu_items_texts(self): return [item.text for item in self.wait_to_be_visible_all(self.Locators.MENU_ITEMS)] @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") - def wait_and_count_builds(self): + def wait_for_build_execution(self): logger.info("Waiting 60 seconds before counting builds...") time.sleep(60) From e87b24b4339bc9b632dcd08aa7a090d1217cbde8 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 23:17:06 +0900 Subject: [PATCH 21/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index 3791766c4..ca72a1185 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -67,11 +67,11 @@ def get_menu_items_texts(self): return [item.text for item in self.wait_to_be_visible_all(self.Locators.MENU_ITEMS)] @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") - def wait_for_build_execution(self): + def wait_for_build_execution(self, timeout=60): logger.info("Waiting 60 seconds before counting builds...") time.sleep(60) builds = self.find_elements(*self.Locators.BUILDS_LINK) count = len(builds) - logger.info(f"{count} build(s) appeared after 60 seconds.") + logger.info(f"{count} build(s) appeared after {timeout} seconds.") return self From d8da2bd97564df5b6b5d4418837c3b4bd5796a07 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 23:23:43 +0900 Subject: [PATCH 22/23] Run tests from tests/api/tests_ui only --- tests/api/tests_ui/freestyle/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index d343b686a..5153b30e2 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -39,7 +39,7 @@ def get_freestyle_scheduled_xml(cls, description: str, timer: str) -> str: - sleep 10 + sleep 35 From 409c93c7dad427c6abe4f64373d012d98136e729 Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 26 Jun 2025 23:33:09 +0900 Subject: [PATCH 23/23] Run tests from tests/api/tests_ui only --- pages/freestyle_project_page.py | 2 +- tests/api/tests_ui/freestyle/data.py | 2 +- tests/api/tests_ui/freestyle/test_build_triggers.py | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pages/freestyle_project_page.py b/pages/freestyle_project_page.py index ca72a1185..aa1654295 100644 --- a/pages/freestyle_project_page.py +++ b/pages/freestyle_project_page.py @@ -69,7 +69,7 @@ def get_menu_items_texts(self): @allure.step("Wait up to {timeout} seconds for the build to appear in the build history.") def wait_for_build_execution(self, timeout=60): logger.info("Waiting 60 seconds before counting builds...") - time.sleep(60) + time.sleep(180) builds = self.find_elements(*self.Locators.BUILDS_LINK) count = len(builds) diff --git a/tests/api/tests_ui/freestyle/data.py b/tests/api/tests_ui/freestyle/data.py index 5153b30e2..0f7c739b2 100644 --- a/tests/api/tests_ui/freestyle/data.py +++ b/tests/api/tests_ui/freestyle/data.py @@ -7,7 +7,7 @@ class CronTimer: every_minute: dict[str, str | int] = { "timer": "*/1 * * * *", "schedule": "1 min", - "timeout": 60 + "timeout": 180 } every_two_minutes: dict[str, str | int] = { "timer": "H/2 * * * *", diff --git a/tests/api/tests_ui/freestyle/test_build_triggers.py b/tests/api/tests_ui/freestyle/test_build_triggers.py index f1982c9d6..afdd00f5d 100644 --- a/tests/api/tests_ui/freestyle/test_build_triggers.py +++ b/tests/api/tests_ui/freestyle/test_build_triggers.py @@ -42,5 +42,7 @@ def test_freestyle_project_ui_fields_match_api_json(create_freestyle_scheduled_p first_build_ui_number = builds_ui[0].split("\n")[1] first_build_json_number = f"#{json_data['builds'][0]['number']}" - + with allure.step("Attach screenshot before asserting number of builds."): + screenshot = main_page.driver.get_screenshot_as_png() + allure.attach(screenshot, name="builds_list_screenshot", attachment_type=allure.attachment_type.PNG) assert first_build_ui_number == first_build_json_number == "#1"