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
5 changes: 3 additions & 2 deletions .github/agents/TestGenerationAgent.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ Generate concise, correct pytest-playwright tests for this repository following
- You will validate that the generated tests adhere to the repository's coding standards and guidelines.

## commands:
- ```pytest``: to run the tests
- ``` black . ```: to format the code
- ```pytest```: to run the tests
- ```black .```: to format the code
- ```mypy .```: to run type checking

handoffs:
- label: Request Code Review
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,14 @@ jobs:
run: |
uv sync --extra dev

- name: Install Playwright browsers
- name: Run Collection
run: |
uv run playwright install --with-deps

- name: Run sanity tests
run: |
uv run pytest tests/ -m sanity -v
uv run pytest tests/ --collect-only

- name: Check code formatting with Black
run: |
uv run black --check .

- name: Run type checking with mypy
run: |
uv run mypy core/ mcp_server/ rag_engine/ tests/
uv run mypy .
2 changes: 1 addition & 1 deletion mcp_server/xray_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def xray_update_test_type(issue_id: str, test_type: str) -> str:

Args:
issue_id: Test issue ID (e.g., "10086")
test_type: Test type name (e.g., "Manual", "Cucumber", "Generic", "Automated[Generic]")
test_type: Test type name (e.g., "Manual", "Cucumber", "Generic", "Automated")

Returns:
JSON string with updated test details
Expand Down
25 changes: 16 additions & 9 deletions plugins/xray.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(

self.graphql_url = "https://xray.cloud.getxray.app/api/v2/graphql"
self.auth_url = "https://xray.cloud.getxray.app/api/v2/authenticate"
self.token = None
self.token: Optional[str] = None
self._authenticate()

def _authenticate(self) -> None:
Expand All @@ -45,9 +45,10 @@ def _authenticate(self) -> None:
headers={"Content-Type": "application/json"},
)
response.raise_for_status()
json_response = response.json()
self.token = (
response.json()
if isinstance(response.json(), str)
json_response
if isinstance(json_response, str)
else response.text.strip('"')
)
except requests.exceptions.RequestException as e:
Expand Down Expand Up @@ -86,7 +87,8 @@ def _execute_query(self, query: str, variables: Optional[Dict] = None) -> Dict:
f"GraphQL errors: {json.dumps(result['errors'], indent=2)}"
)

return result.get("data", {})
data: Dict[Any, Any] = result.get("data", {})
return data
except requests.exceptions.RequestException as e:
raise Exception(f"Failed to execute query: {str(e)}")

Expand Down Expand Up @@ -161,7 +163,8 @@ def get_test_by_key(self, test_key: str) -> Dict:
result = self._execute_query(query, {"jql": jql, "limit": 1})

if result.get("getTests", {}).get("results"):
return result["getTests"]["results"][0]
test_result: Dict[Any, Any] = result["getTests"]["results"][0]
return test_result
return {}

def get_tests_by_label(self, label: str, limit: int = 100) -> List[Dict]:
Expand Down Expand Up @@ -192,7 +195,8 @@ def get_tests_by_label(self, label: str, limit: int = 100) -> List[Dict]:
"""
jql = f'labels = "{label}" AND type = Test'
result = self._execute_query(query, {"jql": jql, "limit": limit})
return result.get("getTests", {}).get("results", [])
tests: List[Dict[Any, Any]] = result.get("getTests", {}).get("results", [])
return tests

# Test Plan Operations

Expand Down Expand Up @@ -258,7 +262,8 @@ def get_test_plan_by_key(self, plan_key: str) -> Dict:
result = self._execute_query(query, {"jql": jql, "limit": 1})

if result.get("getTestPlans", {}).get("results"):
return result["getTestPlans"]["results"][0]
plan_result: Dict[Any, Any] = result["getTestPlans"]["results"][0]
return plan_result
return {}

def add_tests_to_test_plan(
Expand Down Expand Up @@ -504,7 +509,8 @@ def search_tests(self, jql: str, limit: int = 100) -> List[Dict]:
}
"""
result = self._execute_query(query, {"jql": jql, "limit": limit})
return result.get("getTests", {}).get("results", [])
tests: List[Dict[Any, Any]] = result.get("getTests", {}).get("results", [])
return tests

def search_test_plans(self, jql: str, limit: int = 100) -> List[Dict]:
"""
Expand All @@ -529,4 +535,5 @@ def search_test_plans(self, jql: str, limit: int = 100) -> List[Dict]:
}
"""
result = self._execute_query(query, {"jql": jql, "limit": limit})
return result.get("getTestPlans", {}).get("results", [])
plans: List[Dict[Any, Any]] = result.get("getTestPlans", {}).get("results", [])
return plans
1 change: 0 additions & 1 deletion tests/pet_store_api/test_pet_store_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def test_user_creation(
assert response.message == "12345", "Unexpected response message"


@pytest.mark.sanity
def test_user_login(
pet_store_controller: PetStoreController,
) -> None:
Expand Down
12 changes: 12 additions & 0 deletions tests/sauce_ui/test_inventory_page.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest


@pytest.mark.test_case_key("DEV-63")
def test_inventory_page_loads_after_login(logged_in_user):
"""Test that inventory page loads successfully after login.

Expand All @@ -24,6 +25,7 @@ def test_inventory_page_loads_after_login(logged_in_user):
), "Expected page title to be 'Products'"


@pytest.mark.test_case_key("DEV-64")
def test_add_item_to_cart_updates_badge(logged_in_user):
"""Test that adding item to cart updates the cart badge count.

Expand All @@ -49,6 +51,7 @@ def test_add_item_to_cart_updates_badge(logged_in_user):
), "Cart badge should show 1 after adding item"


@pytest.mark.test_case_key("DEV-66")
def test_add_multiple_items_updates_badge_count(logged_in_user):
"""Test that adding multiple items updates the badge count correctly.

Expand All @@ -69,6 +72,7 @@ def test_add_multiple_items_updates_badge_count(logged_in_user):
), "Cart badge should show 3 after adding three items"


@pytest.mark.test_case_key("DEV-73")
def test_remove_item_from_cart_decrements_badge(logged_in_user):
"""Test that removing item from cart decrements the badge count.

Expand All @@ -94,6 +98,7 @@ def test_remove_item_from_cart_decrements_badge(logged_in_user):
), "Cart badge should show 1 after removing one item"


@pytest.mark.test_case_key("DEV-70")
def test_add_to_cart_button_changes_to_remove(logged_in_user):
"""Test that 'Add to cart' button changes to 'Remove' after adding item.

Expand All @@ -117,6 +122,7 @@ def test_add_to_cart_button_changes_to_remove(logged_in_user):
), "Product should be in cart after adding"


@pytest.mark.test_case_key("DEV-69")
@pytest.mark.parametrize(
"sort_option,expected_first,expected_last",
[
Expand Down Expand Up @@ -149,6 +155,7 @@ def test_sort_products_by_name(
assert product_names[-1] == expected_last, f"Last product should be {expected_last}"


@pytest.mark.test_case_key("DEV-72")
def test_all_products_displayed(logged_in_user):
"""Test that all 6 products are displayed on inventory page.

Expand All @@ -164,6 +171,7 @@ def test_all_products_displayed(logged_in_user):
assert len(product_names) == 6, "Inventory page should display 6 products"


@pytest.mark.test_case_key("DEV-74")
def test_cart_state_persists_after_sorting(logged_in_user):
"""Test that cart items persist when sorting products.

Expand All @@ -189,6 +197,7 @@ def test_cart_state_persists_after_sorting(logged_in_user):
), "Cart count should persist after sorting"


@pytest.mark.test_case_key("DEV-71")
def test_remove_all_items_from_cart(logged_in_user):
"""Test that removing all items from cart clears the badge.

Expand All @@ -214,6 +223,7 @@ def test_remove_all_items_from_cart(logged_in_user):
), "Cart badge should be empty after removing all items"


@pytest.mark.test_case_key("DEV-75")
@pytest.mark.parametrize(
"sort_option,expected_first,expected_last",
[
Expand Down Expand Up @@ -248,6 +258,7 @@ def test_sort_products_by_price(
), f"Last product should be {expected_last}, got {product_names[-1]}"


@pytest.mark.test_case_key("DEV-76")
def test_cart_badge_increments_correctly_with_individual_items(logged_in_user):
"""Test that adding multiple different items increments cart badge correctly.

Expand All @@ -269,6 +280,7 @@ def test_cart_badge_increments_correctly_with_individual_items(logged_in_user):
assert logged_in_user.inventory_page.cart_badge_count == "3"


@pytest.mark.test_case_key("DEV-77")
def test_mixed_sorting_and_removal_maintains_correct_cart_count(logged_in_user):
"""Test that cart state is maintained correctly when adding items, sorting, and removing.

Expand Down
4 changes: 3 additions & 1 deletion tests/sauce_ui/test_login_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from core.web.consts import Timeouts


@pytest.mark.sanity
@pytest.mark.test_case_key("DEV-67")
@pytest.mark.parametrize(
"username,password",
[
Expand Down Expand Up @@ -31,6 +31,7 @@ def test_login_with_valid_credentials(sauce_ui, username, password):
), f"Expected redirect to inventory after login with {username}"


@pytest.mark.test_case_key("DEV-65")
def test_login_with_performance_glitch_user(sauce_ui):
"""Test successful login with performance glitch user.

Expand All @@ -56,6 +57,7 @@ def test_login_with_performance_glitch_user(sauce_ui):
), "Expected redirect to inventory after login with performance glitch user"


@pytest.mark.test_case_key("DEV-68")
@pytest.mark.parametrize(
"username,password,expected_error",
[
Expand Down