Skip to content

Commit 84b7f58

Browse files
test: Implemented Log execution time per prompt in Report
2 parents 1ec9c09 + abc5f09 commit 84b7f58

File tree

2 files changed

+119
-61
lines changed

2 files changed

+119
-61
lines changed

tests/e2e-test/pages/homePage.py

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ class HomePage(BasePage):
2020
HIDE_CHAT_HISTORY_BUTTON = "//span[text()='Hide chat history']"
2121
USER_CHAT_MESSAGE = "(//div[contains(@class,'chatMessageUserMessage')])[1]"
2222
STOP_GENERATING_LABEL = "//span[text()='Stop generating']"
23+
# # SHOW_CHAT_HISTORY_BUTTON = "//button[normalize-space()='Show Chat History']"
24+
# HIDE_CHAT_HISTORY_BUTTON = "//button[.//span[text()='Hide chat history']]"
25+
CHAT_HISTORY_NAME = "//div[contains(@class, 'ChatHistoryListItemCell_chatTitle')]"
26+
CLEAR_CHAT_HISTORY_MENU = "//button[@id='moreButton']"
27+
CLEAR_CHAT_HISTORY = "//button[@role='menuitem']"
28+
REFERENCE_LINKS_IN_RESPONSE = "//span[@role='button' and contains(@class, 'citationContainer')]"
29+
CLOSE_BUTTON = "svg[role='button'][tabindex='0']"
2330

2431
def __init__(self, page):
2532
self.page = page
@@ -37,6 +44,31 @@ def enter_a_question(self, text):
3744
self.page.locator(self.TYPE_QUESTION_TEXT_AREA).fill(text)
3845
self.page.wait_for_timeout(2000)
3946

47+
def delete_chat_history(self):
48+
self.page.locator(self.SHOW_CHAT_HISTORY_BUTTON).click()
49+
chat_history = self.page.locator("//span[contains(text(),'No chat history.')]")
50+
if chat_history.is_visible():
51+
self.page.wait_for_load_state('networkidle')
52+
self.page.wait_for_timeout(2000)
53+
self.page.locator(self.HIDE_CHAT_HISTORY_BUTTON).click()
54+
55+
56+
else:
57+
self.page.locator(self.CLEAR_CHAT_HISTORY_MENU).click()
58+
self.page.locator(self.CLEAR_CHAT_HISTORY).click()
59+
self.page.get_by_role("button", name="Clear All").click()
60+
self.page.wait_for_timeout(10000)
61+
self.page.locator(self.HIDE_CHAT_HISTORY_BUTTON).click()
62+
self.page.wait_for_load_state('networkidle')
63+
self.page.wait_for_timeout(2000)
64+
65+
def close_chat_history(self):
66+
self.page.locator(self.HIDE_CHAT_HISTORY_BUTTON).click()
67+
self.page.wait_for_load_state('networkidle')
68+
self.page.wait_for_timeout(2000)
69+
70+
71+
4072
def click_send_button(self):
4173
# Click on send button in question area
4274
self.page.locator(self.SEND_BUTTON).click()
@@ -54,10 +86,6 @@ def validate_next_meeting_date_time(self):
5486
response_raw_datetime = self.page.locator(self.ANSWER_TEXT).text_content()
5587
BasePage.compare_raw_date_time(self,response_raw_datetime,sidepanel_raw_datetime)
5688

57-
def click_on_save_chat_plus_icon(self):
58-
self.page.wait_for_selector(self.SAVE_CHATHISTORY_PLUS_ICON)
59-
self.page.locator(self.SAVE_CHATHISTORY_PLUS_ICON).click()
60-
self.page.wait_for_timeout(1000)
6189

6290
def click_on_show_chat_history_button(self):
6391
self.page.wait_for_selector(self.SHOW_CHAT_HISTORY_BUTTON)
@@ -68,10 +96,6 @@ def click_send_button_for_chat_history_response(self):
6896
# Click on send button in question area
6997
self.page.locator(self.SEND_BUTTON).click()
7098

71-
def click_on_saved_chat(self):
72-
#click on saved chat in the show chat history section
73-
self.page.wait_for_selector(self.SAVED_CHAT_LABEL)
74-
self.page.locator(self.SAVED_CHAT_LABEL).click()
7599

76100
def click_clear_chat_icon(self):
77101
# Click on clear chat icon in question area
@@ -80,4 +104,13 @@ def click_clear_chat_icon(self):
80104

81105
def click_hide_chat_history_button(self):
82106
# Click on hide chat history button in question area
83-
self.page.locator(self.HIDE_CHAT_HISTORY_BUTTON).click()
107+
self.page.locator(self.HIDE_CHAT_HISTORY_BUTTON).click()
108+
109+
def has_reference_link(self):
110+
# Get all assistant messages
111+
assistant_messages = self.page.locator("div.chat-message.assistant")
112+
last_assistant = assistant_messages.nth(assistant_messages.count() - 1)
113+
114+
# Use XPath properly by prefixing with 'xpath='
115+
reference_links = last_assistant.locator("xpath=.//span[@role='button' and contains(@class, 'citationContainer')]")
116+
return reference_links.count() > 0

tests/e2e-test/tests/test_poc_byoc_client_advisor.py

Lines changed: 77 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,84 +3,109 @@
33
import pytest
44
from config.constants import *
55
from pages.homePage import HomePage
6+
import io
67

78
logger = logging.getLogger(__name__)
89

10+
# ----------------- Part A: Functional Tests -----------------
11+
912
def validate_home_and_client(home):
1013
assert homepage_title == home.page.locator(home.HOME_PAGE_TITLE).text_content()
1114
home.select_a_client(client_name)
1215
assert client_name == home.page.locator(home.SELECTED_CLIENT_NAME_LABEL).text_content()
1316

14-
def save_chat_confirmation_popup(home):
15-
home.click_clear_chat_icon()
16-
home.enter_a_question(golden_path_question1)
17-
home.click_send_button()
18-
home.validate_response_status()
19-
home.click_on_save_chat_plus_icon()
20-
assert home.page.locator(home.SAVE_CHAT_CONFIRMATION_POPUPTEXT).is_visible()
21-
2217
def delete_chat_history_during_response(home):
23-
home.enter_a_question(golden_path_question1)
24-
home.click_send_button()
25-
home.click_on_save_chat_plus_icon()
26-
assert home.page.locator(home.SAVE_CHAT_CONFIRMATION_POPUPTEXT).is_visible()
27-
home.click_on_show_chat_history_button()
28-
home.click_on_saved_chat()
29-
home.enter_a_question(golden_path_question1)
30-
home.click_send_button_for_chat_history_response()
31-
assert home.page.locator(home.SHOW_CHAT_HISTORY_DELETE_ICON).is_disabled()
32-
home.click_hide_chat_history_button()
33-
home.click_clear_chat_icon()
34-
35-
def golden_path_full_demo(home):
36-
_validate_golden_path_response(home, golden_path_question1)
37-
_validate_golden_path_response(home, golden_path_question2)
38-
_validate_golden_path_response(home, golden_path_question3)
39-
_validate_golden_path_response(home, golden_path_question4)
40-
_validate_golden_path_response(home, golden_path_question5)
18+
home.delete_chat_history()
19+
# home.close_chat_history()
20+
21+
22+
def validate_client_absence(home):
4123
_validate_client_info_absence(home, golden_path_question7)
4224

43-
# Define test steps and actions
44-
test_cases = [
45-
("Validate homepage and select client", validate_home_and_client),
46-
("Save chat confirmation popup", save_chat_confirmation_popup),
47-
("Delete chat history during response", delete_chat_history_during_response),
48-
("Golden path full demo", golden_path_full_demo),
25+
functional_test_cases = [
26+
("Validate homepage is loaded and select client", validate_home_and_client),
27+
("Validate delete chat history", delete_chat_history_during_response),
28+
]
29+
30+
@pytest.mark.parametrize("desc, action", functional_test_cases, ids=[x[0] for x in functional_test_cases])
31+
def test_functional_flows(login_logout, desc, action, request):
32+
page = login_logout
33+
home_page = HomePage(page)
34+
home_page.page = page
35+
36+
log_capture = io.StringIO()
37+
handler = logging.StreamHandler(log_capture)
38+
logger.addHandler(handler)
39+
40+
logger.info(f"Running step: {desc}")
41+
start = time.time()
42+
try:
43+
action(home_page)
44+
finally:
45+
duration = time.time() - start
46+
logger.info(f"Execution Time for '{desc}': {duration:.2f}s")
47+
logger.removeHandler(handler)
48+
request.node._report_sections.append(("call", "log", log_capture.getvalue()))
49+
50+
# ----------------- Part B: GP Question Tests -----------------
51+
52+
# GP Questions List
53+
gp_questions = [
54+
golden_path_question1,
55+
golden_path_question2,
56+
golden_path_question3,
57+
golden_path_question4,
58+
golden_path_question5
4959
]
5060

51-
# Create readable test IDs
52-
test_ids = [f"{i+1:02d}. {desc}" for i, (desc, _) in enumerate(test_cases)]
61+
# Custom readable test IDs
62+
gp_test_ids = [f"Validate response for prompt: {q[:60]}... " for i, q in enumerate(gp_questions)]
5363

5464
def _validate_golden_path_response(home, question):
5565
home.enter_a_question(question)
5666
home.click_send_button()
5767
home.validate_response_status()
5868
response_text = home.page.locator(home.ANSWER_TEXT)
59-
assert response_text.nth(response_text.count() - 1).text_content() != invalid_response, \
60-
f"Incorrect response for question: {question}"
69+
last_response = response_text.nth(response_text.count() - 1).text_content()
70+
assert last_response != invalid_response, f"Incorrect response for: {question}"
71+
assert last_response != "Chart cannot be generated.", f"Chart error for: {question}"
72+
73+
if home.has_reference_link():
74+
logger.info("Citation link found. Opening citation.")
75+
home.click_reference_link_in_response()
76+
logger.info("Closing citation.")
77+
home.close_citation()
78+
79+
home.click_on_show_chat_history_button()
80+
home.close_chat_history()
81+
6182

6283
def _validate_client_info_absence(home, question):
6384
home.enter_a_question(question)
6485
home.click_send_button()
6586
home.validate_response_status()
66-
response_text = home.page.locator(home.ANSWER_TEXT).nth(home.page.locator(home.ANSWER_TEXT).count() - 1).text_content().lower()
87+
response_text = home.page.locator(home.ANSWER_TEXT).nth(
88+
home.page.locator(home.ANSWER_TEXT).count() - 1
89+
).text_content().lower()
6790
assert "arun sharma" not in response_text, "Other client information appeared in response."
68-
assert client_name.lower() not in response_text, f"Client name '{client_name}' should not be in response for question: {question}"
91+
assert client_name.lower() not in response_text, f"Client name '{client_name}' appeared in response."
6992

70-
@pytest.mark.parametrize("desc, action", test_cases, ids=test_ids)
71-
def test_home_page_cases(login_logout, desc, action, request):
72-
"""
73-
Parametrized test for home page scenarios including chat flows and validations.
74-
"""
93+
@pytest.mark.parametrize("question", gp_questions, ids=gp_test_ids)
94+
def test_gp_questions_individual(login_logout, question, request):
7595
page = login_logout
76-
home_page = HomePage(page)
77-
home_page.page = page # Required for locator access in helper functions
78-
logger.info(f"Running step: {desc}")
96+
home = HomePage(page)
97+
home.page = page
7998

80-
start = time.time()
81-
action(home_page)
82-
end = time.time()
99+
log_capture = io.StringIO()
100+
handler = logging.StreamHandler(log_capture)
101+
logger.addHandler(handler)
83102

84-
duration = end - start
85-
logger.info(f"Execution Time for '{desc}': {duration:.2f}s")
86-
request.node._report_sections.append(("call", "log", f"Execution time: {duration:.2f}s"))
103+
logger.info(f"Running Golden Path test for: {question}")
104+
start = time.time()
105+
try:
106+
_validate_golden_path_response(home, question)
107+
finally:
108+
duration = time.time() - start
109+
logger.info(f"Execution Time for GP Question: {duration:.2f}s")
110+
logger.removeHandler(handler)
111+
request.node._report_sections.append(("call", "log", log_capture.getvalue()))

0 commit comments

Comments
 (0)