Skip to content

Commit e1f3089

Browse files
Merge branch 'dev' of https://github.com/microsoft/Conversation-Knowledge-Mining-Solution-Accelerator into pk-km-inconsistentresponce
2 parents 65606b1 + 3a5676e commit e1f3089

File tree

13 files changed

+1482
-442
lines changed

13 files changed

+1482
-442
lines changed

tests/e2e-test/base/base.py

Lines changed: 24 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -2,140 +2,54 @@
22
BasePage Module
33
Contains base page object class with common methods
44
"""
5+
from config.constants import *
56
import json
6-
import logging
7+
from dotenv import load_dotenv
78
import os
8-
import time
99
import uuid
10-
from dotenv import load_dotenv
11-
from config.constants import API_URL
12-
13-
logger = logging.getLogger(__name__)
14-
10+
import time
1511

1612
class BasePage:
17-
"""Base class for all page objects"""
18-
1913
def __init__(self, page):
20-
"""Initialize BasePage with page instance"""
2114
self.page = page
2215

23-
def scroll_into_view(self, locator):
24-
"""Scroll element into view"""
16+
def scroll_into_view(self,locator):
2517
reference_list = locator
2618
locator.nth(reference_list.count()-1).scroll_into_view_if_needed()
2719

28-
def is_visible(self, locator):
29-
"""Check if element is visible"""
30-
return locator.is_visible()
20+
def is_visible(self,locator):
21+
locator.is_visible()
3122

32-
def validate_response_status(self, question): # pylint: disable=too-many-locals,too-many-statements
33-
"""
34-
Validate that the API responds with status 200 for the given question.
35-
Uses Playwright's request context which maintains authentication from the browser session.
36-
"""
23+
def validate_response_status(self,questions):
3724
load_dotenv()
38-
39-
url = f"{API_URL}/history/update"
25+
WEB_URL = os.getenv("web_url")
26+
27+
url = f"{API_URL}/api/chat"
28+
4029

4130
user_message_id = str(uuid.uuid4())
31+
assistant_message_id = str(uuid.uuid4())
4232
conversation_id = str(uuid.uuid4())
4333

4434
payload = {
45-
"messages": [{"role": "assistant", "content": question, "id": user_message_id}],
35+
"messages": [{"role": "user", "content": questions,
36+
"id": user_message_id}],
4637
"conversation_id": conversation_id,
4738
}
48-
39+
# Serialize the payload to JSON
40+
payload_json = json.dumps(payload)
4941
headers = {
50-
"Content-Type": "application/json",
42+
"Content-Type": "application/json-lines",
5143
"Accept": "*/*"
5244
}
53-
54-
# Log request details for debugging
55-
logger.info("=" * 80)
56-
logger.info("🔍 API REQUEST DEBUG INFO")
57-
logger.info("=" * 80)
58-
logger.info("URL: %s", url)
59-
logger.info("Method: POST")
60-
logger.info("Headers: %s", json.dumps(headers, indent=2))
61-
logger.info("Payload: %s", json.dumps(payload, indent=2))
62-
logger.info("Question: %s", question)
63-
45+
# response = self.page.request.post(url, headers=headers, data=payload_json, timeout=60000)
6446
start = time.time()
47+
response = self.page.request.post(url, headers=headers, data=payload_json, timeout=90000)
48+
duration = time.time() - start
6549

66-
try:
67-
# Using Playwright's request context to leverage browser's authentication
68-
response = self.page.request.post(
69-
url,
70-
headers=headers,
71-
data=json.dumps(payload),
72-
timeout=90000
73-
)
74-
75-
duration = time.time() - start
76-
77-
# Log response details for debugging
78-
logger.info("-" * 80)
79-
logger.info("📥 API RESPONSE DEBUG INFO")
80-
logger.info("-" * 80)
81-
logger.info("Status Code: %s", response.status)
82-
logger.info("Response Time: %.2fs", duration)
83-
84-
# Log response headers
85-
try:
86-
response_headers = response.headers
87-
logger.info("Response Headers: %s", json.dumps(dict(response_headers), indent=2))
88-
except Exception as exc: # pylint: disable=broad-exception-caught
89-
logger.warning("Could not get response headers: %s", str(exc))
90-
91-
# Get response body for debugging
92-
try:
93-
response_body = response.json()
94-
logger.info("Response Body (JSON): %s", json.dumps(response_body, indent=2))
95-
96-
# If there's an error in the response, log it prominently
97-
if "error" in response_body:
98-
logger.error("🚨 API ERROR MESSAGE: %s", response_body.get("error"))
99-
if "detail" in response_body:
100-
logger.error("🚨 API ERROR DETAIL: %s", response_body.get("detail"))
101-
102-
except Exception as exc: # pylint: disable=broad-exception-caught
103-
logger.warning("Could not parse response body as JSON: %s", str(exc))
104-
try:
105-
response_text = response.text()
106-
# First 500 chars
107-
logger.info("Response Body (Text): %s", response_text[:500])
108-
except Exception as text_error: # pylint: disable=broad-exception-caught
109-
logger.error("Could not get response text: %s", str(text_error))
110-
111-
# Assert successful response
112-
if response.status != 200:
113-
error_msg = f"API returned status {response.status} instead of 200"
114-
logger.error("❌ %s", error_msg)
115-
logger.error("💡 POSSIBLE REASONS FOR 500 ERROR:")
116-
logger.error(
117-
" 1. Missing 'conversation_id' in payload (endpoint expects existing conversation)"
118-
)
119-
logger.error(" 2. Authentication/authorization issue")
120-
logger.error(" 3. Invalid payload structure")
121-
logger.error(" 4. Backend service error")
122-
logger.error(" 5. Database connection issue")
123-
logger.warning(
124-
"⚠️ Warning: %s - Continuing with test (UI validation is primary)",
125-
error_msg
126-
)
127-
else:
128-
logger.info("✅ API succeeded in %.2fs", duration)
50+
print(f"✅succeeded in {duration:.2f}s")
51+
# Check the response status code
52+
assert response.status == 200, "response code is " + str(response.status)
12953

130-
except Exception as exc: # pylint: disable=broad-exception-caught
131-
duration = time.time() - start
132-
logger.error("❌ API request failed after %.2fs", duration)
133-
logger.error("Exception Type: %s", type(exc).__name__)
134-
logger.error("Exception Message: %s", str(exc))
135-
import traceback # pylint: disable=import-outside-toplevel
136-
logger.error("Stack Trace:\n%s", traceback.format_exc())
137-
logger.warning("⚠️ Warning: API validation failed - Continuing with test")
54+
self.page.wait_for_timeout(4000)
13855

139-
logger.info("=" * 80)
140-
# Wait for UI to settle
141-
self.page.wait_for_timeout(6000)

tests/e2e-test/config/constants.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
Constants Module
33
Contains configuration constants and loads test data
44
"""
5-
import json
6-
import os
75
from dotenv import load_dotenv
6+
import os
7+
import json
88

99
load_dotenv()
1010
URL = os.getenv('url')
@@ -19,10 +19,20 @@
1919
# Get the absolute path to the repository root
2020
repo_root = os.getenv('GITHUB_WORKSPACE', os.getcwd())
2121

22-
# Construct the absolute path to the JSON file
23-
#note: may have to remove 'tests/e2e-test' from below when running locally
24-
json_file_path = os.path.join(repo_root, 'tests/e2e-test', 'testdata', 'prompts.json')
22+
#remove 'tests/e2e-test' from below path if running locally
23+
24+
# Load Telecom prompts
25+
telecom_json_file_path = os.path.join(repo_root, 'tests/e2e-test', 'testdata', 'telecom_prompts.json')
26+
with open(telecom_json_file_path, 'r') as file:
27+
telecom_data = json.load(file)
28+
telecom_questions = telecom_data['questions']
29+
30+
# Load ITHelpdesk prompts
31+
ithelpdesk_json_file_path = os.path.join(repo_root, 'tests/e2e-test', 'testdata', 'ithelpdesk_prompts.json')
32+
with open(ithelpdesk_json_file_path, 'r') as file:
33+
ithelpdesk_data = json.load(file)
34+
ithelpdesk_questions = ithelpdesk_data['questions']
35+
36+
# Backward compatibility - keep 'questions' as alias for telecom_questions
37+
questions = telecom_questions
2538

26-
with open(json_file_path, 'r', encoding='utf-8') as file:
27-
data = json.load(file)
28-
questions = data['questions']

0 commit comments

Comments
 (0)