@iblai/iblai-js 1.26.10 → 1.26.11

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.
@@ -0,0 +1,262 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ /**
3
+ * Support tab helpers — Playwright bindings for the `AgentHumanSupportTab`
4
+ * component from `@iblai/web-containers` (Edit Agent modal → Runtime →
5
+ * Support).
6
+ *
7
+ * All UI strings below mirror `AGENT_HUMAN_SUPPORT_TAB_LABELS` from
8
+ * `@iblai/web-containers/next`. If a consumer renames a label via the
9
+ * `labels` prop, override these constants per spec — don't edit this file.
10
+ *
11
+ * Scoping rule (see playwright-testing skill §12): capture the Edit Agent
12
+ * dialog FIRST via `getEditAgentDialog(page)`, then resolve every in-panel
13
+ * locator from that dialog. Radix portals (select option lists, popover
14
+ * contents) render OUTSIDE the dialog subtree — those queries intentionally
15
+ * run on the `page` and are commented as such.
16
+ */
17
+ export declare const SUPPORT_LABELS: {
18
+ /** Sidebar segment label (host app) + tab panel value. */
19
+ readonly tabName: "Support";
20
+ /** The host sidebar trigger's `aria-controls` panel id suffix. */
21
+ readonly panelValue: "human_support";
22
+ /** Category strip pill that hosts the Support segment. */
23
+ readonly navCategory: "Runtime";
24
+ readonly header: {
25
+ readonly title: "Support";
26
+ readonly description: "Review and respond to support requests submitted for this agent.";
27
+ };
28
+ readonly toggle: {
29
+ /** `aria-label` on the availability switch in the info box. */
30
+ readonly enable: "Enable support";
31
+ };
32
+ readonly filters: {
33
+ readonly searchUser: "Search for User";
34
+ readonly searchUsersPlaceholder: "Search users...";
35
+ readonly allUsers: "All Users";
36
+ readonly allStatuses: "All Statuses";
37
+ };
38
+ readonly status: {
39
+ readonly open: "Open";
40
+ readonly inProgress: "In Progress";
41
+ readonly closed: "Closed";
42
+ };
43
+ readonly list: {
44
+ readonly noTickets: "No support tickets found";
45
+ readonly untitled: "Support request";
46
+ /** `aria-label` of the ticket-list region. */
47
+ readonly regionLabel: "Support ticket list";
48
+ };
49
+ readonly detail: {
50
+ readonly selectPrompt: "Select a ticket to view details.";
51
+ readonly statusLabel: "Status";
52
+ readonly requestSection: "Request";
53
+ readonly conversationSection: "Conversation";
54
+ readonly supportTeam: "Support Team";
55
+ readonly noMessages: "No replies yet.";
56
+ readonly replyPlaceholder: "Write a reply to the user…";
57
+ readonly sendReply: "Send Reply";
58
+ readonly closedNotice: "This ticket is closed. Set it back to Open or In Progress to reply.";
59
+ /** `aria-label` of the ticket-detail region. */
60
+ readonly regionLabel: "Support ticket details";
61
+ };
62
+ readonly testIds: {
63
+ readonly infoBox: "human-support-info-box";
64
+ readonly toggle: "human-support-toggle";
65
+ readonly ticketList: "human-support-ticket-list";
66
+ readonly ticketDetail: "human-support-ticket-detail";
67
+ readonly ticketDescription: "human-support-ticket-description";
68
+ /** Ticket rows render as `human-support-ticket-item-<id>`. */
69
+ readonly ticketItemPrefix: "human-support-ticket-item-";
70
+ };
71
+ readonly chat: {
72
+ /** Accessible name of the chat textbox in the host app. */
73
+ readonly inputName: "Ask anything";
74
+ readonly sendButton: "Send message";
75
+ /** Stable class markers from `CSS_CLASS_NAMES.CHAT` in web-containers. */
76
+ readonly userQueryClass: ".chat-user-message-query";
77
+ readonly aiResponseClass: ".chat-ai-message-response";
78
+ readonly stopStreamingClass: ".chat-stop-streaming-button";
79
+ };
80
+ };
81
+ /** The three ticket statuses accepted by `setTicketStatus` / filters. */
82
+ export type SupportTicketStatus = keyof typeof SUPPORT_LABELS.status;
83
+ /**
84
+ * Capture the Edit Agent dialog itself. Every other helper resolves its
85
+ * locators from this dialog, so in-panel controls never collide with
86
+ * elements mounted on the page behind the modal.
87
+ *
88
+ * The dialog carries no stable test id in the host, so it is identified by
89
+ * its visible title ("Edit Agent" by default — override for hosts that
90
+ * rename the modal).
91
+ */
92
+ export declare function getEditAgentDialog(page: Page, dialogTitle?: string): Locator;
93
+ /**
94
+ * Check whether the Support tab is currently reachable in the Edit Agent
95
+ * dialog. Returns false instead of throwing so callers can guard
96
+ * permission-gated hosts (the segment is admin-only).
97
+ */
98
+ export declare function isSupportTabVisible(page: Page): Promise<boolean>;
99
+ /**
100
+ * The host sidebar trigger for the Support segment. Matched by its
101
+ * `aria-controls="panel-human_support"` (stable across label renames);
102
+ * `:visible` excludes the hidden responsive twin the host renders for the
103
+ * other breakpoint.
104
+ */
105
+ export declare function getSupportTabTrigger(dialog: Locator): Locator;
106
+ /**
107
+ * Switch to the Support tab. Assumes the Edit Agent dialog is open.
108
+ * Returns the dialog locator so callers can keep every follow-up query
109
+ * scoped without re-capturing it.
110
+ */
111
+ export declare function switchToSupportTab(page: Page): Promise<Locator>;
112
+ /** The info box at the top of the pane (conversational description). */
113
+ export declare function getSupportInfoBox(dialog: Locator): Locator;
114
+ /**
115
+ * The availability switch inside the info box — the same "human support"
116
+ * tool toggle exposed on the Tools tab. Hidden when the tenant's tool
117
+ * catalog has no human-support tool.
118
+ */
119
+ export declare function getSupportToggle(dialog: Locator): Locator;
120
+ /** Read the current on/off state of the availability toggle. */
121
+ export declare function isSupportEnabled(dialog: Locator): Promise<boolean>;
122
+ /**
123
+ * Flip the availability toggle to the requested state (no-op when already
124
+ * there). Waits for `aria-checked` to settle, which tracks the persisted
125
+ * mentor-settings round trip.
126
+ */
127
+ export declare function setSupportEnabled(dialog: Locator, enabled: boolean): Promise<void>;
128
+ /** Turn the support tool on. */
129
+ export declare function enableSupport(dialog: Locator): Promise<void>;
130
+ /** Turn the support tool off. */
131
+ export declare function disableSupport(dialog: Locator): Promise<void>;
132
+ /** The ticket-list region. Only mounted when at least one ticket exists. */
133
+ export declare function getTicketList(dialog: Locator): Locator;
134
+ /**
135
+ * A ticket row matched by (a substring of) its subject. Rows carry
136
+ * `data-testid="human-support-ticket-item-<id>"`; the id is server-side,
137
+ * so text matching within the list is the stable route for specs.
138
+ */
139
+ export declare function getTicketRow(dialog: Locator, subject: string | RegExp): Locator;
140
+ /** A ticket row by its zero-based position in the list. */
141
+ export declare function getTicketRowByIndex(dialog: Locator, index: number): Locator;
142
+ /** Assert a ticket with the given subject text is listed. */
143
+ export declare function expectTicketInList(dialog: Locator, subject: string | RegExp, timeoutMs?: number): Promise<void>;
144
+ /** Assert the empty state ("No support tickets found") is shown. */
145
+ export declare function expectNoTickets(dialog: Locator): Promise<void>;
146
+ /** Assert a listed ticket row shows the expected status badge. */
147
+ export declare function expectTicketStatusInList(dialog: Locator, subject: string | RegExp, status: SupportTicketStatus): Promise<void>;
148
+ /** The status-filter trigger next to the user search. */
149
+ export declare function getStatusFilter(dialog: Locator): Locator;
150
+ /**
151
+ * Filter the list by ticket status ('all' clears the filter). Changing
152
+ * the filter re-queries the backend, so this doubles as a refresh hook.
153
+ */
154
+ export declare function filterTicketsByStatus(dialog: Locator, status: SupportTicketStatus | 'all'): Promise<void>;
155
+ /** The "Search for User" combobox trigger (opens the requester popover). */
156
+ export declare function getUserFilter(dialog: Locator): Locator;
157
+ /**
158
+ * Filter the list by requester. Types `search` into the popover's search
159
+ * box, then clicks the entry whose label (email, else username) matches
160
+ * `optionText`.
161
+ */
162
+ export declare function filterTicketsByUser(dialog: Locator, search: string, optionText?: string | RegExp): Promise<void>;
163
+ /** Clear the requester filter via the "All Users" popover entry. */
164
+ export declare function clearUserFilter(dialog: Locator): Promise<void>;
165
+ /**
166
+ * Force the ticket list to re-query by bouncing the status filter
167
+ * (all → open → all). Each argument change issues a fresh request for
168
+ * uncached filter combinations, which is how specs pick up tickets
169
+ * created out-of-band (e.g. by the agent during a chat).
170
+ */
171
+ export declare function refreshTickets(dialog: Locator): Promise<void>;
172
+ /**
173
+ * Wait for a ticket to appear in the list, refreshing between polls.
174
+ * Agent-created tickets land after the chat tool call completes
175
+ * server-side, so allow a generous deadline.
176
+ *
177
+ * Pass `opts.refresh` to override the default status-filter bounce with a
178
+ * stronger strategy (e.g. close and re-open the modal, or reload the page
179
+ * and navigate back) — the callback runs between polls and must leave the
180
+ * Support tab open.
181
+ */
182
+ export declare function waitForTicketInList(dialog: Locator, subject: string | RegExp, opts?: {
183
+ timeoutMs?: number;
184
+ refresh?: () => Promise<void>;
185
+ }): Promise<void>;
186
+ /** The detail pane (desktop two-column layout). */
187
+ export declare function getTicketDetail(dialog: Locator): Locator;
188
+ /** The rendered ticket body (HTML/Markdown/plain, already formatted). */
189
+ export declare function getTicketDescription(dialog: Locator): Locator;
190
+ /**
191
+ * Open a ticket from the list and wait for its detail to render. Returns
192
+ * the detail pane locator for chained assertions.
193
+ */
194
+ export declare function openTicket(dialog: Locator, subject: string | RegExp): Promise<Locator>;
195
+ /** Assert the opened ticket's rendered body contains the given text. */
196
+ export declare function expectTicketDescriptionContains(dialog: Locator, text: string | RegExp): Promise<void>;
197
+ /**
198
+ * Change the opened ticket's status via the detail pane's Status select.
199
+ * Selecting "Closed" routes through the dedicated close endpoint and
200
+ * replaces the composer with the closed notice.
201
+ */
202
+ export declare function setTicketStatus(dialog: Locator, status: SupportTicketStatus): Promise<void>;
203
+ /** Assert the closed notice is shown (composer hidden). */
204
+ export declare function expectTicketClosedNotice(dialog: Locator): Promise<void>;
205
+ /** The reply composer textarea in the opened ticket. */
206
+ export declare function getReplyComposer(dialog: Locator): Locator;
207
+ /**
208
+ * Send a reply on the opened ticket and wait for the composer to clear
209
+ * (the component empties it only after the API call succeeds).
210
+ */
211
+ export declare function replyToTicket(dialog: Locator, message: string): Promise<void>;
212
+ /** Assert a message (from either side) is visible in the conversation. */
213
+ export declare function expectMessageInConversation(dialog: Locator, message: string | RegExp): Promise<void>;
214
+ /** Assert the opened ticket has no replies yet. */
215
+ export declare function expectNoRepliesYet(dialog: Locator): Promise<void>;
216
+ /** The main chat textbox. */
217
+ export declare function getChatInput(page: Page): Locator;
218
+ /**
219
+ * Send a message to the agent from the main chat surface and wait for the
220
+ * user bubble to render. Does NOT wait for the AI response — pair with
221
+ * `waitForAgentChatResponse`.
222
+ */
223
+ export declare function sendAgentChatMessage(page: Page, message: string): Promise<void>;
224
+ /**
225
+ * Wait for the agent's reply to finish. LLM latency plus tool execution
226
+ * (the support-ticket tool call) makes this the slow step — default 90s.
227
+ * Returns the reply text for content assertions.
228
+ */
229
+ export declare function waitForAgentChatResponse(page: Page, timeoutMs?: number): Promise<string>;
230
+ /**
231
+ * Ask the agent (via chat) to open a support ticket with a distinctive
232
+ * subject, and wait for its reply. The explicit "subject" phrasing gives
233
+ * the support tool an exact string to file, which the spec then looks
234
+ * for in the ticket list.
235
+ */
236
+ export declare function requestSupportTicketViaChat(page: Page, opts: {
237
+ subject: string;
238
+ description?: string;
239
+ }): Promise<string>;
240
+ /**
241
+ * Full flow: with support enabled, ask the agent for a ticket in chat,
242
+ * then verify it shows up in the Support tab.
243
+ *
244
+ * The Edit Agent modal is host-specific to open/close, so the caller
245
+ * provides `openEditAgentModal` (and optionally `closeEditAgentModal`,
246
+ * used to get the modal out of the chat's way before sending). Steps:
247
+ *
248
+ * 1. `openEditAgentModal()` → Support tab → ensure the toggle is ON.
249
+ * 2. `closeEditAgentModal()` (when provided) → chat-request the ticket.
250
+ * 3. `openEditAgentModal()` → Support tab → wait for the ticket row.
251
+ *
252
+ * Returns the dialog locator with the Support tab open and the new
253
+ * ticket listed, so specs can keep asserting (open it, reply, close it).
254
+ */
255
+ export declare function createSupportTicketViaChatAndVerify(page: Page, opts: {
256
+ subject: string;
257
+ description?: string;
258
+ openEditAgentModal: () => Promise<void>;
259
+ closeEditAgentModal?: () => Promise<void>;
260
+ /** Deadline for the ticket to appear in the list (default 90s). */
261
+ listTimeoutMs?: number;
262
+ }): Promise<Locator>;
@@ -35,5 +35,6 @@ export { TASKS_LABELS, isTasksTabVisible, switchToTasksTab, getScheduleTaskButto
35
35
  export type { TaskRepeat, TaskStatus } from './tasks-tab-helpers';
36
36
  export * from './evaluation-tab-helpers';
37
37
  export * from './lti-tab-helpers';
38
+ export * from './human-support-tab-helpers';
38
39
  export { createPlaywrightConfig, generateProjectConfig, generateBrowserSetupProjects, getBrowserKey, } from './playwright-config';
39
40
  export type { PlatformConfig, CreatePlaywrightConfigOptions } from './playwright-config';