codemie-test-harness 0.1.167__py3-none-any.whl → 0.1.169__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codemie-test-harness might be problematic. Click here for more details.
- codemie_test_harness/tests/test_data/assistant_test_data.py +197 -0
- codemie_test_harness/tests/ui/assistants/__init__.py +0 -0
- codemie_test_harness/tests/ui/assistants/test_create_assistant.py +408 -0
- codemie_test_harness/tests/ui/conftest.py +23 -3
- codemie_test_harness/tests/ui/pageobject/assistants/assistants_page.py +3 -4
- codemie_test_harness/tests/ui/pageobject/assistants/create_assistant_page.py +689 -0
- codemie_test_harness/tests/ui/pageobject/assistants/generate_with_ai_modal.py +367 -0
- codemie_test_harness/tests/ui/pageobject/base_page.py +24 -24
- codemie_test_harness/tests/ui/pageobject/components/__init__.py +2 -2
- codemie_test_harness/tests/ui/pageobject/components/execution_history_row.py +3 -3
- codemie_test_harness/tests/ui/pageobject/components/{header.py → menu.py} +57 -111
- codemie_test_harness/tests/ui/pageobject/components/pop_up.py +2 -2
- codemie_test_harness/tests/ui/pageobject/components/workflow_card.py +7 -10
- codemie_test_harness/tests/ui/pageobject/components/workflow_execution_history_item.py +9 -9
- codemie_test_harness/tests/ui/pageobject/components/workflow_execution_state.py +1 -1
- codemie_test_harness/tests/ui/pageobject/components/workflow_sidebar.py +16 -16
- codemie_test_harness/tests/ui/pageobject/workflows/base_workflow_form_page.py +32 -65
- codemie_test_harness/tests/ui/pageobject/workflows/create_workflow_page.py +4 -4
- codemie_test_harness/tests/ui/pageobject/workflows/edit_workflow_page.py +6 -4
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_details_page.py +32 -61
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_executions_page.py +17 -23
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_template_details.py +5 -11
- codemie_test_harness/tests/ui/pageobject/workflows/workflow_templates_page.py +5 -2
- codemie_test_harness/tests/ui/pageobject/workflows/workflows_page.py +3 -5
- codemie_test_harness/tests/ui/pytest.ini +18 -0
- codemie_test_harness/tests/ui/workflows/__init__.py +0 -0
- codemie_test_harness/tests/ui/{test_create_workflow.py → workflows/test_create_workflow.py} +12 -33
- codemie_test_harness/tests/ui/{test_edit_workflow.py → workflows/test_edit_workflow.py} +14 -34
- codemie_test_harness/tests/ui/{test_workflow_details.py → workflows/test_workflow_details.py} +11 -11
- codemie_test_harness/tests/ui/{test_workflow_executions_page.py → workflows/test_workflow_executions_page.py} +0 -2
- codemie_test_harness/tests/ui/{test_workflow_templates.py → workflows/test_workflow_templates.py} +0 -2
- codemie_test_harness/tests/ui/{test_workflows.py → workflows/test_workflows.py} +8 -6
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.169.dist-info}/METADATA +2 -2
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.169.dist-info}/RECORD +36 -29
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.169.dist-info}/WHEEL +0 -0
- {codemie_test_harness-0.1.167.dist-info → codemie_test_harness-0.1.169.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from playwright.sync_api import Page, expect
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AIAssistantGeneratorPage:
|
|
9
|
+
"""
|
|
10
|
+
Page Object Model for the Generate Assistant with AI form.
|
|
11
|
+
|
|
12
|
+
This form allows users to create AI assistants by describing their requirements
|
|
13
|
+
and configuring various options including tool integrations.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, page: Page):
|
|
17
|
+
"""
|
|
18
|
+
Initialize the AI Assistant Generator page object.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
page: Playwright page instance
|
|
22
|
+
"""
|
|
23
|
+
self.page = page
|
|
24
|
+
self._setup_locators()
|
|
25
|
+
|
|
26
|
+
def _setup_locators(self) -> None:
|
|
27
|
+
"""Define all locators for the AI Assistant Generator form based on actual HTML structure."""
|
|
28
|
+
|
|
29
|
+
# Modal container
|
|
30
|
+
self.modal_container = self.page.locator(".popup").filter(
|
|
31
|
+
has_text="Generate Assistant with AI"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Header elements
|
|
35
|
+
self.modal_header = self.modal_container.locator(".popup-header.withBorder")
|
|
36
|
+
self.modal_title = self.modal_header.locator("h4")
|
|
37
|
+
self.close_button = self.modal_header.locator(
|
|
38
|
+
'button[aria-label="Close popup"]'
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Modal body
|
|
42
|
+
self.modal_body = self.modal_container.locator(".popup-body")
|
|
43
|
+
|
|
44
|
+
# Description elements - Updated based on actual structure
|
|
45
|
+
self.description_text = self.modal_body.locator("p").first
|
|
46
|
+
self.assistant_description_label = self.modal_body.locator("p").nth(1)
|
|
47
|
+
|
|
48
|
+
# Main textarea - Updated with actual name attribute
|
|
49
|
+
self.assistant_description_textarea = (
|
|
50
|
+
self.modal_body.locator('textarea[name="ai_generation_prompt"]')
|
|
51
|
+
.or_(self.modal_body.locator(".textarea-wrapper textarea"))
|
|
52
|
+
.or_(self.modal_body.locator("textarea.textarea"))
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Checkbox elements - Updated with actual IDs
|
|
56
|
+
self.do_not_show_checkbox = (
|
|
57
|
+
self.modal_body.locator('input#dont_show[type="checkbox"]')
|
|
58
|
+
.or_(self.modal_body.locator('input[name="dont_show"]'))
|
|
59
|
+
.or_(self.modal_body.locator('.p-checkbox input[type="checkbox"]'))
|
|
60
|
+
)
|
|
61
|
+
self.do_not_show_label = self.modal_body.locator('label[for="dont_show"]')
|
|
62
|
+
|
|
63
|
+
# Include tools toggle - Updated with actual ID
|
|
64
|
+
self.include_tools_toggle = (
|
|
65
|
+
self.modal_body.locator('input#include_tools[type="checkbox"]')
|
|
66
|
+
.or_(self.modal_body.locator('input[name="include_tools"]'))
|
|
67
|
+
.or_(self.modal_body.locator('.switch-wrapper input[type="checkbox"]'))
|
|
68
|
+
)
|
|
69
|
+
self.include_tools_label = self.modal_body.locator(".switch-wrapper .label")
|
|
70
|
+
|
|
71
|
+
# Action buttons - Updated based on actual button classes
|
|
72
|
+
self.create_manually_button = (
|
|
73
|
+
self.modal_body.locator(
|
|
74
|
+
'button.button.secondary:has-text("Create Manualy")'
|
|
75
|
+
)
|
|
76
|
+
.or_(self.modal_body.locator('button:has-text("Create Manualy")'))
|
|
77
|
+
.or_(self.modal_body.locator(".button.secondary"))
|
|
78
|
+
)
|
|
79
|
+
self.generate_with_ai_button = (
|
|
80
|
+
self.modal_body.locator(
|
|
81
|
+
'button.button.primary:has-text("Generate with AI")'
|
|
82
|
+
)
|
|
83
|
+
.or_(self.modal_body.locator('button:has-text("Generate with AI")'))
|
|
84
|
+
.or_(self.modal_body.locator(".button.primary"))
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Note text - Updated based on actual structure
|
|
88
|
+
self.integration_note = self.modal_body.locator(".text-text-secondary.text-xs")
|
|
89
|
+
self.info_icon = self.modal_body.locator(".flex.w-full.px-2 svg").first
|
|
90
|
+
|
|
91
|
+
# Navigation and state methods
|
|
92
|
+
|
|
93
|
+
def wait_for_modal_to_load(self, timeout: float = 10000) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Wait for the AI Assistant Generator modal to be fully loaded and visible.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
timeout: Maximum time to wait in milliseconds
|
|
99
|
+
"""
|
|
100
|
+
logger.info("Waiting for AI Assistant Generator modal to load")
|
|
101
|
+
expect(self.modal_container).to_be_visible(timeout=timeout)
|
|
102
|
+
expect(self.modal_title).to_be_visible()
|
|
103
|
+
expect(self.assistant_description_textarea).to_be_visible()
|
|
104
|
+
logger.info("AI Assistant Generator modal loaded successfully")
|
|
105
|
+
|
|
106
|
+
def is_modal_visible(self) -> bool:
|
|
107
|
+
"""
|
|
108
|
+
Check if the AI Assistant Generator modal is currently visible.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
True if modal is visible, False otherwise
|
|
112
|
+
"""
|
|
113
|
+
return self.modal_container.is_visible()
|
|
114
|
+
|
|
115
|
+
def close_modal(self) -> None:
|
|
116
|
+
"""Close the AI Assistant Generator modal using the close button."""
|
|
117
|
+
logger.info("Closing AI Assistant Generator modal")
|
|
118
|
+
self.close_button.click()
|
|
119
|
+
expect(self.modal_container).not_to_be_visible()
|
|
120
|
+
logger.info("AI Assistant Generator modal closed successfully")
|
|
121
|
+
|
|
122
|
+
# Form interaction methods
|
|
123
|
+
|
|
124
|
+
def enter_assistant_description(self, description: str) -> None:
|
|
125
|
+
"""
|
|
126
|
+
Enter description text in the assistant description textarea.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
description: The assistant description text to enter
|
|
130
|
+
"""
|
|
131
|
+
logger.info(f"Entering assistant description: {description[:50]}...")
|
|
132
|
+
self.assistant_description_textarea.click()
|
|
133
|
+
self.assistant_description_textarea.clear()
|
|
134
|
+
self.assistant_description_textarea.fill(description)
|
|
135
|
+
|
|
136
|
+
# Verify the text was entered correctly
|
|
137
|
+
expect(self.assistant_description_textarea).to_have_value(description)
|
|
138
|
+
logger.info("Assistant description entered successfully")
|
|
139
|
+
|
|
140
|
+
def get_assistant_description(self) -> str:
|
|
141
|
+
"""
|
|
142
|
+
Get the current value of the assistant description textarea.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Current text value in the description textarea
|
|
146
|
+
"""
|
|
147
|
+
return self.assistant_description_textarea.input_value()
|
|
148
|
+
|
|
149
|
+
def toggle_do_not_show_popup(self, enabled: bool = True) -> None:
|
|
150
|
+
"""
|
|
151
|
+
Toggle the "Do not show this popup" checkbox.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
enabled: True to check the checkbox, False to uncheck
|
|
155
|
+
"""
|
|
156
|
+
logger.info(f"Setting 'Do not show popup' to: {enabled}")
|
|
157
|
+
|
|
158
|
+
if enabled and not self.do_not_show_checkbox.is_checked():
|
|
159
|
+
self.do_not_show_checkbox.check()
|
|
160
|
+
elif not enabled and self.do_not_show_checkbox.is_checked():
|
|
161
|
+
self.do_not_show_checkbox.uncheck()
|
|
162
|
+
|
|
163
|
+
# Verify the state
|
|
164
|
+
if enabled:
|
|
165
|
+
expect(self.do_not_show_checkbox).to_be_checked()
|
|
166
|
+
else:
|
|
167
|
+
expect(self.do_not_show_checkbox).not_to_be_checked()
|
|
168
|
+
|
|
169
|
+
logger.info(f"'Do not show popup' checkbox set to: {enabled}")
|
|
170
|
+
|
|
171
|
+
def is_do_not_show_popup_checked(self) -> bool:
|
|
172
|
+
"""
|
|
173
|
+
Check if the "Do not show this popup" checkbox is checked.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
True if checkbox is checked, False otherwise
|
|
177
|
+
"""
|
|
178
|
+
return self.do_not_show_checkbox.is_checked()
|
|
179
|
+
|
|
180
|
+
def toggle_include_tools(self, enabled: bool = True) -> None:
|
|
181
|
+
"""
|
|
182
|
+
Toggle the "Include Tools" option.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
enabled: True to enable tools inclusion, False to disable
|
|
186
|
+
"""
|
|
187
|
+
logger.info(f"Setting 'Include Tools' to: {enabled}")
|
|
188
|
+
|
|
189
|
+
if enabled and not self.include_tools_toggle.is_checked():
|
|
190
|
+
self.include_tools_toggle.check()
|
|
191
|
+
elif not enabled and self.include_tools_toggle.is_checked():
|
|
192
|
+
self.include_tools_toggle.uncheck()
|
|
193
|
+
|
|
194
|
+
# Verify the state
|
|
195
|
+
if enabled:
|
|
196
|
+
expect(self.include_tools_toggle).to_be_checked()
|
|
197
|
+
else:
|
|
198
|
+
expect(self.include_tools_toggle).not_to_be_checked()
|
|
199
|
+
|
|
200
|
+
logger.info(f"'Include Tools' toggle set to: {enabled}")
|
|
201
|
+
|
|
202
|
+
def is_include_tools_enabled(self) -> bool:
|
|
203
|
+
"""
|
|
204
|
+
Check if the "Include Tools" toggle is enabled.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
True if toggle is enabled, False otherwise
|
|
208
|
+
"""
|
|
209
|
+
return self.include_tools_toggle.is_checked()
|
|
210
|
+
|
|
211
|
+
# Action methods
|
|
212
|
+
|
|
213
|
+
def click_create_manually(self) -> None:
|
|
214
|
+
"""Click the 'Create Manually' button."""
|
|
215
|
+
logger.info("Clicking 'Create Manually' button")
|
|
216
|
+
expect(self.create_manually_button).to_be_enabled()
|
|
217
|
+
self.create_manually_button.click()
|
|
218
|
+
logger.info("'Create Manually' button clicked")
|
|
219
|
+
|
|
220
|
+
def click_generate_with_ai(self) -> None:
|
|
221
|
+
"""Click the 'Generate with AI' button."""
|
|
222
|
+
logger.info("Clicking 'Generate with AI' button")
|
|
223
|
+
expect(self.generate_with_ai_button).to_be_enabled()
|
|
224
|
+
self.generate_with_ai_button.click()
|
|
225
|
+
logger.info("'Generate with AI' button clicked")
|
|
226
|
+
|
|
227
|
+
# Validation methods
|
|
228
|
+
|
|
229
|
+
def is_generate_button_enabled(self) -> bool:
|
|
230
|
+
"""
|
|
231
|
+
Check if the 'Generate with AI' button is enabled.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
True if button is enabled, False otherwise
|
|
235
|
+
"""
|
|
236
|
+
return self.generate_with_ai_button.is_enabled()
|
|
237
|
+
|
|
238
|
+
def is_create_manually_button_enabled(self) -> bool:
|
|
239
|
+
"""
|
|
240
|
+
Check if the 'Create Manually' button is enabled.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
True if button is enabled, False otherwise
|
|
244
|
+
"""
|
|
245
|
+
return self.create_manually_button.is_enabled()
|
|
246
|
+
|
|
247
|
+
def validate_form_elements_visible(self) -> None:
|
|
248
|
+
"""Validate that all expected form elements are visible and accessible."""
|
|
249
|
+
logger.info("Validating AI Assistant Generator form elements visibility")
|
|
250
|
+
|
|
251
|
+
# Check modal structure
|
|
252
|
+
expect(self.modal_container).to_be_visible()
|
|
253
|
+
expect(self.modal_title).to_be_visible()
|
|
254
|
+
expect(self.close_button).to_be_visible()
|
|
255
|
+
|
|
256
|
+
# Check form elements
|
|
257
|
+
expect(self.assistant_description_label).to_be_visible()
|
|
258
|
+
expect(self.assistant_description_textarea).to_be_visible()
|
|
259
|
+
expect(self.do_not_show_label).to_be_visible()
|
|
260
|
+
expect(self.do_not_show_checkbox).to_be_visible()
|
|
261
|
+
expect(self.include_tools_label).to_be_visible()
|
|
262
|
+
expect(self.include_tools_toggle).to_be_visible()
|
|
263
|
+
|
|
264
|
+
# Check action buttons
|
|
265
|
+
expect(self.create_manually_button).to_be_visible()
|
|
266
|
+
expect(self.generate_with_ai_button).to_be_visible()
|
|
267
|
+
|
|
268
|
+
# Check note text
|
|
269
|
+
expect(self.integration_note).to_be_visible()
|
|
270
|
+
|
|
271
|
+
logger.info("All form elements are visible and accessible")
|
|
272
|
+
|
|
273
|
+
def validate_textarea_placeholder(self) -> None:
|
|
274
|
+
"""Validate that the textarea has the expected placeholder text."""
|
|
275
|
+
placeholder_text = self.assistant_description_textarea.get_attribute(
|
|
276
|
+
"placeholder"
|
|
277
|
+
)
|
|
278
|
+
expected_text = "For example: I need a project assistant that helps track deadlines, work with Jira and help with business requirements"
|
|
279
|
+
|
|
280
|
+
assert expected_text in placeholder_text, (
|
|
281
|
+
f"Placeholder text mismatch. Expected: {expected_text}, Got: {placeholder_text}"
|
|
282
|
+
)
|
|
283
|
+
logger.info("Textarea placeholder validation passed")
|
|
284
|
+
|
|
285
|
+
def verify_modal_title(self) -> None:
|
|
286
|
+
"""Verify the modal has the correct title."""
|
|
287
|
+
expect(self.modal_title).to_have_text("Generate Assistant with AI")
|
|
288
|
+
logger.info("Modal title verification passed")
|
|
289
|
+
|
|
290
|
+
def verify_description_text(self) -> None:
|
|
291
|
+
"""Verify the main description text is present."""
|
|
292
|
+
expect(self.description_text).to_contain_text("Describe your ideal assistant")
|
|
293
|
+
logger.info("Description text verification passed")
|
|
294
|
+
|
|
295
|
+
def verify_prompt_label(self) -> None:
|
|
296
|
+
"""Verify the prompt question is displayed."""
|
|
297
|
+
expect(self.assistant_description_label).to_have_text(
|
|
298
|
+
"What should your assistant do?"
|
|
299
|
+
)
|
|
300
|
+
logger.info("Prompt label verification passed")
|
|
301
|
+
|
|
302
|
+
def verify_note_text(self) -> None:
|
|
303
|
+
"""Verify the note about tool integrations."""
|
|
304
|
+
expect(self.integration_note).to_contain_text(
|
|
305
|
+
"Note: Please select tool integrations after generation"
|
|
306
|
+
)
|
|
307
|
+
logger.info("Note text verification passed")
|
|
308
|
+
|
|
309
|
+
# Composite action methods
|
|
310
|
+
|
|
311
|
+
def fill_and_generate_assistant(
|
|
312
|
+
self,
|
|
313
|
+
description: str,
|
|
314
|
+
include_tools: bool = True,
|
|
315
|
+
do_not_show_again: bool = False,
|
|
316
|
+
) -> None:
|
|
317
|
+
"""
|
|
318
|
+
Complete workflow to fill the form and generate an AI assistant.
|
|
319
|
+
|
|
320
|
+
Args:
|
|
321
|
+
description: Assistant description text
|
|
322
|
+
include_tools: Whether to include tools in the assistant
|
|
323
|
+
do_not_show_again: Whether to check "do not show popup" option
|
|
324
|
+
"""
|
|
325
|
+
logger.info("Starting complete assistant generation workflow")
|
|
326
|
+
|
|
327
|
+
# Wait for modal to be ready
|
|
328
|
+
self.wait_for_modal_to_load()
|
|
329
|
+
|
|
330
|
+
# Fill form fields
|
|
331
|
+
self.enter_assistant_description(description)
|
|
332
|
+
self.toggle_include_tools(include_tools)
|
|
333
|
+
self.toggle_do_not_show_popup(do_not_show_again)
|
|
334
|
+
|
|
335
|
+
# Generate the assistant
|
|
336
|
+
self.click_generate_with_ai()
|
|
337
|
+
|
|
338
|
+
logger.info("Assistant generation workflow completed")
|
|
339
|
+
|
|
340
|
+
def fill_and_create_manually(
|
|
341
|
+
self,
|
|
342
|
+
description: str,
|
|
343
|
+
include_tools: bool = True,
|
|
344
|
+
do_not_show_again: bool = False,
|
|
345
|
+
) -> None:
|
|
346
|
+
"""
|
|
347
|
+
Complete workflow to fill the form and create assistant manually.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
description: Assistant description text
|
|
351
|
+
include_tools: Whether to include tools in the assistant
|
|
352
|
+
do_not_show_again: Whether to check "do not show popup" option
|
|
353
|
+
"""
|
|
354
|
+
logger.info("Starting manual assistant creation workflow")
|
|
355
|
+
|
|
356
|
+
# Wait for modal to be ready
|
|
357
|
+
self.wait_for_modal_to_load()
|
|
358
|
+
|
|
359
|
+
# Fill form fields
|
|
360
|
+
self.enter_assistant_description(description)
|
|
361
|
+
self.toggle_include_tools(include_tools)
|
|
362
|
+
self.toggle_do_not_show_popup(do_not_show_again)
|
|
363
|
+
|
|
364
|
+
# Create manually
|
|
365
|
+
self.click_create_manually()
|
|
366
|
+
|
|
367
|
+
logger.info("Manual assistant creation workflow completed")
|
|
@@ -3,8 +3,8 @@ import re
|
|
|
3
3
|
from playwright.sync_api import expect
|
|
4
4
|
from reportportal_client import step
|
|
5
5
|
|
|
6
|
+
from codemie_test_harness.tests.ui.pageobject.components.menu import Menu
|
|
6
7
|
from codemie_test_harness.tests.ui.pageobject.components.pop_up import PopUp
|
|
7
|
-
from codemie_test_harness.tests.ui.pageobject.components.header import Header
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class BasePage:
|
|
@@ -16,7 +16,7 @@ class BasePage:
|
|
|
16
16
|
# Component properties using @property decorator
|
|
17
17
|
@property
|
|
18
18
|
def back_button(self):
|
|
19
|
-
"""Back button in the
|
|
19
|
+
"""Back button in the menu."""
|
|
20
20
|
return self.page.locator(
|
|
21
21
|
'//div[not(contains(@class,"justify-end"))]/button[contains(@class,"secondary medium")]'
|
|
22
22
|
).first
|
|
@@ -27,9 +27,9 @@ class BasePage:
|
|
|
27
27
|
return PopUp(self.page)
|
|
28
28
|
|
|
29
29
|
@property
|
|
30
|
-
def
|
|
31
|
-
"""
|
|
32
|
-
return
|
|
30
|
+
def menu(self):
|
|
31
|
+
"""Menu component instance."""
|
|
32
|
+
return Menu(self.page)
|
|
33
33
|
|
|
34
34
|
# Common page elements
|
|
35
35
|
@property
|
|
@@ -55,44 +55,44 @@ class BasePage:
|
|
|
55
55
|
# Navigation methods
|
|
56
56
|
@step
|
|
57
57
|
def go_to_workflows_page(self):
|
|
58
|
-
"""Navigate to workflows page using
|
|
59
|
-
self.
|
|
58
|
+
"""Navigate to workflows page using menu navigation."""
|
|
59
|
+
self.menu.navigate_to_workflows()
|
|
60
60
|
return self
|
|
61
61
|
|
|
62
62
|
@step
|
|
63
63
|
def go_to_assistants_page(self):
|
|
64
|
-
"""Navigate to assistants page using
|
|
65
|
-
self.
|
|
64
|
+
"""Navigate to assistants page using menu navigation."""
|
|
65
|
+
self.menu.navigate_to_assistants()
|
|
66
66
|
return self
|
|
67
67
|
|
|
68
68
|
@step
|
|
69
69
|
def go_to_chats_page(self):
|
|
70
|
-
"""Navigate to chats page using
|
|
71
|
-
self.
|
|
70
|
+
"""Navigate to chats page using menu navigation."""
|
|
71
|
+
self.menu.navigate_to_chats()
|
|
72
72
|
return self
|
|
73
73
|
|
|
74
74
|
@step
|
|
75
75
|
def go_to_applications_page(self):
|
|
76
|
-
"""Navigate to applications page using
|
|
77
|
-
self.
|
|
76
|
+
"""Navigate to applications page using menu navigation."""
|
|
77
|
+
self.menu.navigate_to_applications()
|
|
78
78
|
return self
|
|
79
79
|
|
|
80
80
|
@step
|
|
81
81
|
def go_to_integrations_page(self):
|
|
82
|
-
"""Navigate to integrations page using
|
|
83
|
-
self.
|
|
82
|
+
"""Navigate to integrations page using menu navigation."""
|
|
83
|
+
self.menu.navigate_to_integrations()
|
|
84
84
|
return self
|
|
85
85
|
|
|
86
86
|
@step
|
|
87
87
|
def go_to_data_sources_page(self):
|
|
88
|
-
"""Navigate to data sources page using
|
|
89
|
-
self.
|
|
88
|
+
"""Navigate to data sources page using menu navigation."""
|
|
89
|
+
self.menu.navigate_to_data_sources()
|
|
90
90
|
return self
|
|
91
91
|
|
|
92
92
|
@step
|
|
93
93
|
def go_to_help_page(self):
|
|
94
|
-
"""Navigate to help page using
|
|
95
|
-
self.
|
|
94
|
+
"""Navigate to help page using menu navigation."""
|
|
95
|
+
self.menu.navigate_to_help()
|
|
96
96
|
return self
|
|
97
97
|
|
|
98
98
|
# Pop-up interaction methods
|
|
@@ -164,10 +164,10 @@ class BasePage:
|
|
|
164
164
|
"""Verify that the new release popup is visible with expected content."""
|
|
165
165
|
expect(self.pop_up.cancel).to_have_text("Got It, Thanks!")
|
|
166
166
|
expect(self.pop_up.submit).to_have_text("Tell Me More")
|
|
167
|
-
expect(self.pop_up.
|
|
167
|
+
expect(self.pop_up.menu).to_have_text("New CodeMie Release")
|
|
168
168
|
expect(self.pop_up.body).to_have_text(
|
|
169
169
|
re.compile(
|
|
170
|
-
r"Great news! We've rolled out new CodeMie version
|
|
170
|
+
r"Great news! We've rolled out new CodeMie version \d.\d.\d+ to enhance your experience. Take a moment to "
|
|
171
171
|
"explore what's new and discover how these changes can benefit you! Please review Release Notes!"
|
|
172
172
|
)
|
|
173
173
|
)
|
|
@@ -182,9 +182,9 @@ class BasePage:
|
|
|
182
182
|
|
|
183
183
|
# Common verification methods
|
|
184
184
|
@step
|
|
185
|
-
def
|
|
186
|
-
"""Verify that the
|
|
187
|
-
self.
|
|
185
|
+
def should_have_menu_visible(self):
|
|
186
|
+
"""Verify that the menu is visible."""
|
|
187
|
+
self.menu.should_be_visible()
|
|
188
188
|
return self
|
|
189
189
|
|
|
190
190
|
@step
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from .workflow_card import WorkflowCard
|
|
2
2
|
from .pop_up import PopUp
|
|
3
|
-
from .
|
|
3
|
+
from .menu import Menu
|
|
4
4
|
from .workflow_sidebar import WorkflowSidebar
|
|
5
5
|
from .execution_history_row import ExecutionHistoryRow
|
|
6
6
|
from .workflow_state_card import WorkflowStateCard
|
|
@@ -10,7 +10,7 @@ from .workflow_execution_state import WorkflowExecutionState
|
|
|
10
10
|
__all__ = [
|
|
11
11
|
"WorkflowCard",
|
|
12
12
|
"PopUp",
|
|
13
|
-
"
|
|
13
|
+
"Menu",
|
|
14
14
|
"WorkflowSidebar",
|
|
15
15
|
"ExecutionHistoryRow",
|
|
16
16
|
"WorkflowStateCard",
|
|
@@ -122,7 +122,7 @@ class ExecutionHistoryRow:
|
|
|
122
122
|
self.should_have_status("In Progress")
|
|
123
123
|
expect(self.status_badge).to_have_class("bg-in-progress-secondary")
|
|
124
124
|
expect(self.status_badge).to_have_class("text-in-progress-main")
|
|
125
|
-
expect(self.status_badge).to_have_class("border-in-progress-
|
|
125
|
+
expect(self.status_badge).to_have_class("border-in-progress-border")
|
|
126
126
|
expect(self.status_dot).to_have_class("animate-pulse")
|
|
127
127
|
|
|
128
128
|
@step
|
|
@@ -131,7 +131,7 @@ class ExecutionHistoryRow:
|
|
|
131
131
|
self.should_have_status("Succeeded")
|
|
132
132
|
expect(self.status_badge).to_contain_class("bg-success-secondary")
|
|
133
133
|
expect(self.status_badge).to_contain_class("text-success-main")
|
|
134
|
-
expect(self.status_badge).to_contain_class("border-success-
|
|
134
|
+
expect(self.status_badge).to_contain_class("border-success-border")
|
|
135
135
|
|
|
136
136
|
@step
|
|
137
137
|
def should_have_failed_status(self):
|
|
@@ -139,7 +139,7 @@ class ExecutionHistoryRow:
|
|
|
139
139
|
self.should_have_status("Failed")
|
|
140
140
|
expect(self.status_badge).to_contain_class("bg-error-secondary")
|
|
141
141
|
expect(self.status_badge).to_contain_class("text-error-main")
|
|
142
|
-
expect(self.status_badge).to_contain_class("border-error-
|
|
142
|
+
expect(self.status_badge).to_contain_class("border-error-border")
|
|
143
143
|
|
|
144
144
|
@step
|
|
145
145
|
def should_have_prompt(self, expected_prompt: str):
|