@iblai/iblai-js 1.26.8 → 1.26.10
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.
- package/dist/data-layer/security/index.d.ts +1 -0
- package/dist/data-layer/security/next.d.ts +1 -0
- package/dist/playwright/security/index.d.ts +1 -0
- package/dist/playwright/security/next.d.ts +1 -0
- package/dist/security/data-layer/index.d.ts +1 -0
- package/dist/security/index.d.ts +1 -0
- package/dist/security/index.esm.js +2 -0
- package/dist/security/index.esm.js.map +1 -0
- package/dist/security/index.js +13 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/next.d.ts +1 -0
- package/dist/security/next.esm.js +2 -0
- package/dist/security/next.esm.js.map +1 -0
- package/dist/security/next.js +13 -0
- package/dist/security/next.js.map +1 -0
- package/dist/security/playwright/audit-log-helpers.d.ts +119 -0
- package/dist/security/playwright/auth-flow-builder.d.ts +13 -0
- package/dist/security/playwright/auth-helpers.d.ts +10 -0
- package/dist/security/playwright/auth-setup.d.ts +34 -0
- package/dist/security/playwright/billing-tab-helpers.d.ts +88 -0
- package/dist/security/playwright/chat-privacy-helpers.d.ts +127 -0
- package/dist/security/playwright/claw-sandbox-helpers.d.ts +266 -0
- package/dist/security/playwright/credit-balance-helpers.d.ts +73 -0
- package/dist/security/playwright/custom-reporter.d.ts +12 -0
- package/dist/security/playwright/env-config.d.ts +24 -0
- package/dist/security/playwright/evaluation-tab-helpers.d.ts +396 -0
- package/dist/security/playwright/helpers.d.ts +11 -0
- package/dist/security/playwright/index.d.ts +39 -0
- package/dist/security/playwright/logger.d.ts +3 -0
- package/dist/security/playwright/lti-tab-helpers.d.ts +270 -0
- package/dist/security/playwright/mail-client.d.ts +46 -0
- package/dist/security/playwright/memory-test-helpers.d.ts +66 -0
- package/dist/security/playwright/navigation.d.ts +26 -0
- package/dist/security/playwright/page-helpers.d.ts +38 -0
- package/dist/security/playwright/playwright-config.d.ts +81 -0
- package/dist/security/playwright/privacy-tab-helpers.d.ts +95 -0
- package/dist/security/playwright/report-download.d.ts +71 -0
- package/dist/security/playwright/screenshare-tab-helpers.d.ts +57 -0
- package/dist/security/playwright/shared-test-helpers.d.ts +37 -0
- package/dist/security/playwright/tasks-tab-helpers.d.ts +177 -0
- package/dist/security/playwright/voice-tab-helpers.d.ts +194 -0
- package/dist/security/security/index.d.ts +1 -0
- package/dist/security/security/next.d.ts +1 -0
- package/dist/security/web-containers/index.d.ts +1 -0
- package/dist/security/web-containers/next.d.ts +1 -0
- package/dist/security/web-containers/sso.d.ts +1 -0
- package/dist/security/web-utils/auth.d.ts +1 -0
- package/dist/security/web-utils/index.d.ts +1 -0
- package/dist/web-containers/security/index.d.ts +1 -0
- package/dist/web-containers/security/next.d.ts +1 -0
- package/dist/web-containers/source/index.esm.js +10 -8
- package/dist/web-containers/source/next/index.esm.js +10 -8
- package/dist/web-utils/security/index.d.ts +1 -0
- package/dist/web-utils/security/next.d.ts +1 -0
- package/package.json +14 -4
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { Locator, Page } from '@playwright/test';
|
|
2
|
+
/**
|
|
3
|
+
* LTI tab helpers — Playwright bindings for the `AgentLtiTab` component from
|
|
4
|
+
* `@iblai/web-containers`.
|
|
5
|
+
*
|
|
6
|
+
* The LTI tab is a peer top-level tab in the Edit Mentor (Agent) dialog with
|
|
7
|
+
* four sub-tabs: Links, Keys, Tools, and Tool Endpoints. It only renders when
|
|
8
|
+
* the agent is LTI-accessible (`is_lti_accessible`), so navigation helpers
|
|
9
|
+
* return `false` rather than throwing when the tab is absent.
|
|
10
|
+
*
|
|
11
|
+
* SELECTOR POLICY: every locator below resolves via a stable `data-testid`,
|
|
12
|
+
* an `aria-label`, or an accessible role+name (tab / button / menuitem /
|
|
13
|
+
* heading text). No CSS class or structural selectors are used, so these
|
|
14
|
+
* helpers survive styling changes.
|
|
15
|
+
*
|
|
16
|
+
* The helpers assume the Edit Mentor dialog is already open. Call
|
|
17
|
+
* `switchToLtiTab(page)` first; most helpers accept either the `Page` or the
|
|
18
|
+
* dialog `Locator` as `scope`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const LTI_LABELS: {
|
|
21
|
+
/** Left-sidebar tab name. */
|
|
22
|
+
readonly tabName: "LTI";
|
|
23
|
+
readonly header: {
|
|
24
|
+
readonly title: "LTI";
|
|
25
|
+
readonly description: "Manage LTI agent links, signing keys, tools, and platform endpoints.";
|
|
26
|
+
};
|
|
27
|
+
readonly subTabs: {
|
|
28
|
+
readonly agentLinks: "Links";
|
|
29
|
+
readonly keys: "Keys";
|
|
30
|
+
readonly tools: "Tools";
|
|
31
|
+
readonly toolEndpoints: "Tool Endpoints";
|
|
32
|
+
};
|
|
33
|
+
readonly modals: {
|
|
34
|
+
readonly createLink: "Create LTI Link";
|
|
35
|
+
readonly editLink: "Edit LTI Link";
|
|
36
|
+
readonly createKey: "Create LTI Key";
|
|
37
|
+
readonly keyDetail: "LTI Key";
|
|
38
|
+
readonly deleteKey: "Delete LTI Key";
|
|
39
|
+
readonly createTool: "Create LTI Tool";
|
|
40
|
+
readonly editTool: "Edit LTI Tool";
|
|
41
|
+
};
|
|
42
|
+
readonly buttons: {
|
|
43
|
+
readonly createLink: "Create LTI Link";
|
|
44
|
+
readonly createKey: "Create LTI Key";
|
|
45
|
+
readonly createTool: "Create LTI Tool";
|
|
46
|
+
/** Confirm button inside the delete-key modal. */
|
|
47
|
+
readonly deleteKey: "Delete";
|
|
48
|
+
readonly edit: "Edit";
|
|
49
|
+
readonly delete: "Delete";
|
|
50
|
+
readonly cancel: "Cancel";
|
|
51
|
+
readonly close: "Close";
|
|
52
|
+
readonly save: "Save";
|
|
53
|
+
readonly create: "Create";
|
|
54
|
+
};
|
|
55
|
+
readonly empty: {
|
|
56
|
+
readonly links: "No LTI link yet for this agent.";
|
|
57
|
+
readonly keys: "No LTI keys yet.";
|
|
58
|
+
readonly tools: "No LTI tools yet.";
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
/** data-testid values rendered by the LTI components. */
|
|
62
|
+
export declare const LTI_TEST_IDS: {
|
|
63
|
+
readonly tabBody: "lti-tab-body";
|
|
64
|
+
readonly subTabs: "lti-sub-tabs";
|
|
65
|
+
readonly subTab: {
|
|
66
|
+
readonly agentLinks: "lti-sub-tab-agent-links";
|
|
67
|
+
readonly keys: "lti-sub-tab-keys";
|
|
68
|
+
readonly tools: "lti-sub-tab-tools";
|
|
69
|
+
readonly toolEndpoints: "lti-sub-tab-tool-endpoints";
|
|
70
|
+
};
|
|
71
|
+
readonly links: {
|
|
72
|
+
readonly section: "lti-links-section";
|
|
73
|
+
readonly createButton: "lti-link-create-button";
|
|
74
|
+
readonly empty: "lti-links-empty";
|
|
75
|
+
readonly row: "lti-link-row";
|
|
76
|
+
readonly modal: "lti-link-modal";
|
|
77
|
+
readonly nameInput: "lti-link-name-input";
|
|
78
|
+
};
|
|
79
|
+
readonly keys: {
|
|
80
|
+
readonly section: "lti-keys-section";
|
|
81
|
+
readonly createButton: "lti-key-create-button";
|
|
82
|
+
readonly empty: "lti-keys-empty";
|
|
83
|
+
readonly row: "lti-key-row";
|
|
84
|
+
readonly createModal: "lti-key-create-modal";
|
|
85
|
+
readonly createNameInput: "lti-key-name-input";
|
|
86
|
+
readonly detailModal: "lti-key-detail-modal";
|
|
87
|
+
readonly detailNameInput: "lti-key-detail-name-input";
|
|
88
|
+
readonly publicKey: "lti-key-public-key";
|
|
89
|
+
readonly publicJwk: "lti-key-public-jwk";
|
|
90
|
+
readonly deleteModal: "lti-key-delete-modal";
|
|
91
|
+
};
|
|
92
|
+
readonly tools: {
|
|
93
|
+
readonly section: "lti-tools-section";
|
|
94
|
+
readonly createButton: "lti-tool-create-button";
|
|
95
|
+
readonly empty: "lti-tools-empty";
|
|
96
|
+
readonly row: "lti-tool-row";
|
|
97
|
+
readonly modal: "lti-tool-modal";
|
|
98
|
+
readonly titleInput: "lti-tool-title-input";
|
|
99
|
+
readonly issuerInput: "lti-tool-issuer-input";
|
|
100
|
+
readonly clientIdInput: "lti-tool-client-id-input";
|
|
101
|
+
readonly authLoginInput: "lti-tool-auth-login-input";
|
|
102
|
+
readonly authTokenInput: "lti-tool-auth-token-input";
|
|
103
|
+
readonly authAudienceInput: "lti-tool-auth-audience-input";
|
|
104
|
+
readonly keySetModeUrl: "lti-tool-keyset-mode-url";
|
|
105
|
+
readonly keySetModeRaw: "lti-tool-keyset-mode-raw";
|
|
106
|
+
readonly jwksUrlInput: "lti-tool-jwks-url-input";
|
|
107
|
+
readonly jwksJsonInput: "lti-tool-jwks-json-input";
|
|
108
|
+
readonly keySelect: "lti-tool-key-select";
|
|
109
|
+
readonly deploymentIdsInput: "lti-tool-deployment-ids-input";
|
|
110
|
+
};
|
|
111
|
+
readonly endpoints: {
|
|
112
|
+
readonly redirectUri: "lti-endpoint-redirect-uri";
|
|
113
|
+
readonly login: "lti-endpoint-login";
|
|
114
|
+
readonly deepLinking: "lti-endpoint-deep-linking";
|
|
115
|
+
readonly jwks: "lti-endpoint-jwks";
|
|
116
|
+
readonly url: "lti-endpoint-url";
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
export type LtiSubTab = keyof typeof LTI_TEST_IDS.subTab;
|
|
120
|
+
export type LtiEndpoint = 'redirectUri' | 'login' | 'deepLinking' | 'jwks';
|
|
121
|
+
export type LtiKeySetMode = 'url' | 'raw';
|
|
122
|
+
/** Fields accepted by `createTool` / `editTool`. */
|
|
123
|
+
export interface LtiToolFormData {
|
|
124
|
+
title: string;
|
|
125
|
+
issuer: string;
|
|
126
|
+
clientId: string;
|
|
127
|
+
authLoginUrl: string;
|
|
128
|
+
authTokenUrl: string;
|
|
129
|
+
authAudience?: string;
|
|
130
|
+
/** Defaults to 'url'. */
|
|
131
|
+
keySetMode?: LtiKeySetMode;
|
|
132
|
+
/** Required when keySetMode === 'url'. */
|
|
133
|
+
jwksUrl?: string;
|
|
134
|
+
/** Required when keySetMode === 'raw' (raw JWKS JSON string). */
|
|
135
|
+
jwksJson?: string;
|
|
136
|
+
/** Name of the signing key to pick from the dropdown. */
|
|
137
|
+
signingKeyName: string;
|
|
138
|
+
/** Deployment ids; joined with newlines into the textarea. */
|
|
139
|
+
deploymentIds?: string[];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Whether the LTI tab is currently available in the Edit Mentor dialog.
|
|
143
|
+
* Returns `false` instead of throwing (the tab is hidden unless the agent is
|
|
144
|
+
* LTI-accessible).
|
|
145
|
+
*/
|
|
146
|
+
export declare function isLtiTabVisible(page: Page): Promise<boolean>;
|
|
147
|
+
/**
|
|
148
|
+
* Switch to the LTI tab. Assumes the Edit Mentor dialog is open. Waits for the
|
|
149
|
+
* sub-tab bar to be interactive before returning.
|
|
150
|
+
*/
|
|
151
|
+
export declare function switchToLtiTab(page: Page): Promise<void>;
|
|
152
|
+
/** Locator for a sub-tab trigger. */
|
|
153
|
+
export declare function getLtiSubTab(scope: Page | Locator, subTab: LtiSubTab): Locator;
|
|
154
|
+
/** Switch to one of the four LTI sub-tabs and wait for it to become active. */
|
|
155
|
+
export declare function switchToLtiSubTab(page: Page, subTab: LtiSubTab): Promise<void>;
|
|
156
|
+
export declare function expectLtiHeader(scope: Page | Locator): Promise<void>;
|
|
157
|
+
export declare function getLinksSection(scope: Page | Locator): Locator;
|
|
158
|
+
/** The "Create LTI Link" button (only shown when no link exists yet). */
|
|
159
|
+
export declare function getCreateLinkButton(scope: Page | Locator): Locator;
|
|
160
|
+
export declare function getLinksEmptyState(scope: Page | Locator): Locator;
|
|
161
|
+
/** A link row located by its visible name. */
|
|
162
|
+
export declare function getLinkRow(scope: Page | Locator, name: string): Locator;
|
|
163
|
+
/** The per-row "Edit <name>" pencil button. */
|
|
164
|
+
export declare function getLinkEditButton(scope: Page | Locator, name: string): Locator;
|
|
165
|
+
/** The "Copy target link URI" button shown in a link row. */
|
|
166
|
+
export declare function getLinkCopyTargetUriButton(scope: Page | Locator): Locator;
|
|
167
|
+
export declare function getLinkModal(scope: Page | Locator): Locator;
|
|
168
|
+
export declare function getLinkNameInput(scope: Page | Locator): Locator;
|
|
169
|
+
export declare function openCreateLinkModal(scope: Page | Locator): Promise<void>;
|
|
170
|
+
export declare function openEditLinkModal(scope: Page | Locator, name: string): Promise<void>;
|
|
171
|
+
/** Type a name into the (already-open) link modal. */
|
|
172
|
+
export declare function fillLinkName(scope: Page | Locator, name: string): Promise<void>;
|
|
173
|
+
export declare function submitLinkModal(scope: Page | Locator): Promise<void>;
|
|
174
|
+
/** Full create-link flow. */
|
|
175
|
+
export declare function createLink(scope: Page | Locator, name: string): Promise<void>;
|
|
176
|
+
/** Full rename-link flow (opens via the row's edit pencil). */
|
|
177
|
+
export declare function editLink(scope: Page | Locator, currentName: string, newName: string): Promise<void>;
|
|
178
|
+
export declare function expectLinksEmpty(scope: Page | Locator): Promise<void>;
|
|
179
|
+
export declare function expectLinkInList(scope: Page | Locator, name: string): Promise<void>;
|
|
180
|
+
export declare function expectLinkNotInList(scope: Page | Locator, name: string): Promise<void>;
|
|
181
|
+
export declare function expectLinkTargetUri(scope: Page | Locator, name: string, targetUri: string): Promise<void>;
|
|
182
|
+
export declare function getKeysSection(scope: Page | Locator): Locator;
|
|
183
|
+
export declare function getCreateKeyButton(scope: Page | Locator): Locator;
|
|
184
|
+
export declare function getKeysEmptyState(scope: Page | Locator): Locator;
|
|
185
|
+
export declare function getKeyRow(scope: Page | Locator, name: string): Locator;
|
|
186
|
+
/** The per-row three-dots "Actions for <name>" menu trigger. */
|
|
187
|
+
export declare function getKeyActionsTrigger(scope: Page | Locator, name: string): Locator;
|
|
188
|
+
/** Open a key's three-dots menu and return the open menu (portal-rendered). */
|
|
189
|
+
export declare function openKeyActionsMenu(scope: Page | Locator, name: string): Promise<Locator>;
|
|
190
|
+
export declare function getKeyCreateModal(scope: Page | Locator): Locator;
|
|
191
|
+
export declare function getKeyCreateNameInput(scope: Page | Locator): Locator;
|
|
192
|
+
export declare function openCreateKeyModal(scope: Page | Locator): Promise<void>;
|
|
193
|
+
export declare function createKey(scope: Page | Locator, name: string): Promise<void>;
|
|
194
|
+
export declare function getKeyDetailModal(scope: Page | Locator): Locator;
|
|
195
|
+
export declare function getKeyDetailNameInput(scope: Page | Locator): Locator;
|
|
196
|
+
export declare function getKeyPublicKeyField(scope: Page | Locator): Locator;
|
|
197
|
+
export declare function getKeyPublicJwkField(scope: Page | Locator): Locator;
|
|
198
|
+
/** Open the detail (edit) modal for a key via its actions menu → Edit. */
|
|
199
|
+
export declare function openKeyDetail(scope: Page | Locator, name: string): Promise<void>;
|
|
200
|
+
/** Read the displayed public key (PEM) value. */
|
|
201
|
+
export declare function readKeyPublicKey(scope: Page | Locator): Promise<string>;
|
|
202
|
+
/** Read the displayed public JWK value. */
|
|
203
|
+
export declare function readKeyPublicJwk(scope: Page | Locator): Promise<string>;
|
|
204
|
+
/** Rename a key via the detail modal (opens the menu → Edit, then Save). */
|
|
205
|
+
export declare function renameKey(scope: Page | Locator, name: string, newName: string): Promise<void>;
|
|
206
|
+
export declare function closeKeyDetail(scope: Page | Locator): Promise<void>;
|
|
207
|
+
export declare function getKeyDeleteModal(scope: Page | Locator): Locator;
|
|
208
|
+
/** Open the delete confirmation for a key via its actions menu → Delete. */
|
|
209
|
+
export declare function openKeyDelete(scope: Page | Locator, name: string): Promise<void>;
|
|
210
|
+
export declare function confirmKeyDelete(scope: Page | Locator): Promise<void>;
|
|
211
|
+
export declare function cancelKeyDelete(scope: Page | Locator): Promise<void>;
|
|
212
|
+
/** Full delete-key flow (menu → Delete → confirm), expects the modal to close. */
|
|
213
|
+
export declare function deleteKey(scope: Page | Locator, name: string): Promise<void>;
|
|
214
|
+
/**
|
|
215
|
+
* Assert the delete error (e.g. "key is associated with tool X"). The backend
|
|
216
|
+
* returns 400/409 and the message is surfaced as a toast (matching the app's
|
|
217
|
+
* delete-modal convention); the modal stays open so the user can cancel.
|
|
218
|
+
*/
|
|
219
|
+
export declare function expectKeyDeleteError(scope: Page | Locator, message: string): Promise<void>;
|
|
220
|
+
export declare function expectKeysEmpty(scope: Page | Locator): Promise<void>;
|
|
221
|
+
export declare function expectKeyInList(scope: Page | Locator, name: string): Promise<void>;
|
|
222
|
+
export declare function expectKeyNotInList(scope: Page | Locator, name: string): Promise<void>;
|
|
223
|
+
export declare function getToolsSection(scope: Page | Locator): Locator;
|
|
224
|
+
export declare function getCreateToolButton(scope: Page | Locator): Locator;
|
|
225
|
+
export declare function getToolsEmptyState(scope: Page | Locator): Locator;
|
|
226
|
+
export declare function getToolRow(scope: Page | Locator, name: string): Locator;
|
|
227
|
+
export declare function getToolEditButton(scope: Page | Locator, name: string): Locator;
|
|
228
|
+
export declare function getToolModal(scope: Page | Locator): Locator;
|
|
229
|
+
/** Field locators inside the (open) tool modal. */
|
|
230
|
+
export declare const toolFields: {
|
|
231
|
+
title: (scope: Page | Locator) => Locator;
|
|
232
|
+
issuer: (scope: Page | Locator) => Locator;
|
|
233
|
+
clientId: (scope: Page | Locator) => Locator;
|
|
234
|
+
authLoginUrl: (scope: Page | Locator) => Locator;
|
|
235
|
+
authTokenUrl: (scope: Page | Locator) => Locator;
|
|
236
|
+
authAudience: (scope: Page | Locator) => Locator;
|
|
237
|
+
jwksUrl: (scope: Page | Locator) => Locator;
|
|
238
|
+
jwksJson: (scope: Page | Locator) => Locator;
|
|
239
|
+
deploymentIds: (scope: Page | Locator) => Locator;
|
|
240
|
+
};
|
|
241
|
+
export declare function getToolKeySelect(scope: Page | Locator): Locator;
|
|
242
|
+
export declare function openCreateToolModal(scope: Page | Locator): Promise<void>;
|
|
243
|
+
export declare function openEditToolModal(scope: Page | Locator, name: string): Promise<void>;
|
|
244
|
+
/** Pick the JWKS source (URL or raw JSON) in the open tool modal. */
|
|
245
|
+
export declare function selectToolKeySetMode(scope: Page | Locator, mode: LtiKeySetMode): Promise<void>;
|
|
246
|
+
/** Pick a signing key by name from the Radix select in the open tool modal. */
|
|
247
|
+
export declare function selectToolSigningKey(scope: Page | Locator, name: string): Promise<void>;
|
|
248
|
+
/** Fill every field of the open tool modal from `data`. */
|
|
249
|
+
export declare function fillToolForm(scope: Page | Locator, data: LtiToolFormData): Promise<void>;
|
|
250
|
+
export declare function submitToolModal(scope: Page | Locator): Promise<void>;
|
|
251
|
+
/** Full create-tool flow. */
|
|
252
|
+
export declare function createTool(scope: Page | Locator, data: LtiToolFormData): Promise<void>;
|
|
253
|
+
/** Full edit-tool flow (opens via the row's edit pencil, applies overrides). */
|
|
254
|
+
export declare function editTool(scope: Page | Locator, name: string, data: LtiToolFormData): Promise<void>;
|
|
255
|
+
export declare function expectToolsEmpty(scope: Page | Locator): Promise<void>;
|
|
256
|
+
export declare function expectToolInList(scope: Page | Locator, name: string): Promise<void>;
|
|
257
|
+
export declare function expectToolNotInList(scope: Page | Locator, name: string): Promise<void>;
|
|
258
|
+
/** Container for a single platform endpoint row. */
|
|
259
|
+
export declare function getEndpoint(scope: Page | Locator, endpoint: LtiEndpoint): Locator;
|
|
260
|
+
/** The `<code>` element holding an endpoint's URL. */
|
|
261
|
+
export declare function getEndpointUrl(scope: Page | Locator, endpoint: LtiEndpoint): Locator;
|
|
262
|
+
/** The per-endpoint "Copy URL" button. */
|
|
263
|
+
export declare function getEndpointCopyButton(scope: Page | Locator, endpoint: LtiEndpoint): Locator;
|
|
264
|
+
/** Read an endpoint URL string. */
|
|
265
|
+
export declare function readEndpointUrl(scope: Page | Locator, endpoint: LtiEndpoint): Promise<string>;
|
|
266
|
+
/** Click an endpoint's copy button; the button label flips to "Copied". */
|
|
267
|
+
export declare function copyEndpoint(scope: Page | Locator, endpoint: LtiEndpoint): Promise<void>;
|
|
268
|
+
export declare function expectEndpointUrl(scope: Page | Locator, endpoint: LtiEndpoint, url: string): Promise<void>;
|
|
269
|
+
/** Assert all four endpoints render with non-empty URLs. */
|
|
270
|
+
export declare function expectAllEndpointsVisible(scope: Page | Locator): Promise<void>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
interface MailsacEmail {
|
|
2
|
+
_id: string;
|
|
3
|
+
from: Array<{
|
|
4
|
+
address: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
}>;
|
|
7
|
+
to: Array<{
|
|
8
|
+
address: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
}>;
|
|
11
|
+
subject: string;
|
|
12
|
+
inbox: string;
|
|
13
|
+
received: string;
|
|
14
|
+
size: number;
|
|
15
|
+
attachments: string[];
|
|
16
|
+
ip: string;
|
|
17
|
+
via: string;
|
|
18
|
+
folder: string;
|
|
19
|
+
labels: string[];
|
|
20
|
+
read: boolean;
|
|
21
|
+
rtls: boolean;
|
|
22
|
+
originalInbox: string;
|
|
23
|
+
spam: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare class MailsacClient {
|
|
26
|
+
private apiKey;
|
|
27
|
+
private baseUrl;
|
|
28
|
+
constructor(apiKey: string);
|
|
29
|
+
/**
|
|
30
|
+
* Get all emails for a specific inbox
|
|
31
|
+
* @param inbox - The inbox address (e.g., 'test@mailsac.com' or just 'test')
|
|
32
|
+
*/
|
|
33
|
+
getEmails(inbox: string): Promise<MailsacEmail[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Get a specific email by ID
|
|
36
|
+
* @param email - The email address
|
|
37
|
+
* @param messageId - The ID of the email to fetch
|
|
38
|
+
*/
|
|
39
|
+
getEmailById(email: string, messageId: string): Promise<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Delete a specific email by ID
|
|
42
|
+
* @param emailId - The ID of the email to delete
|
|
43
|
+
*/
|
|
44
|
+
deleteEmail(emailId: string): Promise<any>;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Locator, Page } from '@playwright/test';
|
|
2
|
+
/**
|
|
3
|
+
* Check if the Memory tab is visible in the profile modal.
|
|
4
|
+
* Returns true if the tab exists and is visible, false otherwise.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isMemoryTabVisible(page: Page): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Switch to the Memory tab in the profile modal.
|
|
9
|
+
* Assumes the profile modal is already open and the Memory tab is visible.
|
|
10
|
+
*/
|
|
11
|
+
export declare function switchToMemoryTab(page: Page): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Verify that Memory tab settings section is visible with both toggles.
|
|
14
|
+
*/
|
|
15
|
+
export declare function verifyMemoryTabSettings(page: Page): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Verify that the "My Memories" section is visible with Add Memory button.
|
|
18
|
+
*/
|
|
19
|
+
export declare function verifyMemoryTabMemoriesList(page: Page): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Open the Add Memory dialog from the Memory tab.
|
|
22
|
+
* Assumes the Memory tab is active.
|
|
23
|
+
*/
|
|
24
|
+
export declare function openAddMemoryDialog(page: Page): Promise<Locator>;
|
|
25
|
+
/**
|
|
26
|
+
* Toggle a memory setting switch and verify the state changes.
|
|
27
|
+
* Returns the new checked state.
|
|
28
|
+
*/
|
|
29
|
+
export declare function toggleMemorySwitch(page: Page, switchName: RegExp | string): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Add a memory via the Add Memory dialog.
|
|
32
|
+
* Opens the dialog, fills content, saves, and waits for dialog to close.
|
|
33
|
+
*/
|
|
34
|
+
export declare function addMemory(page: Page, content: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Delete the first visible memory in the list.
|
|
37
|
+
* Hovers to reveal the delete button, then clicks it.
|
|
38
|
+
*/
|
|
39
|
+
export declare function deleteFirstMemory(page: Page): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Delete a specific memory by matching its content text.
|
|
42
|
+
* Finds the memory item containing the text, hovers to reveal
|
|
43
|
+
* the delete button, and clicks it.
|
|
44
|
+
*/
|
|
45
|
+
export declare function deleteMemoryByContent(page: Page, content: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Use `deleteFirstMemory` instead. Archive was renamed to Delete.
|
|
48
|
+
*/
|
|
49
|
+
export declare const archiveFirstMemory: typeof deleteFirstMemory;
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated Use `deleteMemoryByContent` instead. Archive was renamed to Delete.
|
|
52
|
+
*/
|
|
53
|
+
export declare const archiveMemoryByContent: typeof deleteMemoryByContent;
|
|
54
|
+
/**
|
|
55
|
+
* Get the count of visible memory items in the list.
|
|
56
|
+
* Returns 0 if the empty state is shown.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getMemoryCount(page: Page): Promise<number>;
|
|
59
|
+
/**
|
|
60
|
+
* Verify that a memory with the given content text exists in the list.
|
|
61
|
+
*/
|
|
62
|
+
export declare function verifyMemoryExists(page: Page, content: string): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Verify that a memory with the given content text does NOT exist in the list.
|
|
65
|
+
*/
|
|
66
|
+
export declare function verifyMemoryNotExists(page: Page, content: string): Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Page } from '@playwright/test';
|
|
2
|
+
export interface SafeWaitForURLOptions {
|
|
3
|
+
timeout?: number;
|
|
4
|
+
waitUntil?: 'commit' | 'domcontentloaded' | 'load' | 'networkidle';
|
|
5
|
+
maxRetries?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Check if the current browser is Firefox
|
|
9
|
+
*/
|
|
10
|
+
export declare function isFirefox(page: Page): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Safe wrapper around page.waitForURL that handles browser-specific navigation errors
|
|
13
|
+
*
|
|
14
|
+
* Firefox has stricter navigation lifecycle handling that can cause NS_BINDING_ABORTED
|
|
15
|
+
* errors when multiple rapid navigations occur (React router redirects, auth redirects).
|
|
16
|
+
*
|
|
17
|
+
* Safari can throw "Navigation canceled by policy check" errors during cross-origin
|
|
18
|
+
* navigations or when security policies interrupt the navigation flow.
|
|
19
|
+
*
|
|
20
|
+
* This utility:
|
|
21
|
+
* 1. Uses `waitUntil: 'commit'` for Firefox (faster, avoids abort)
|
|
22
|
+
* 2. Includes retry logic for NS_BINDING_ABORTED errors (Firefox)
|
|
23
|
+
* 3. Handles "Navigation canceled by policy check" errors (Safari)
|
|
24
|
+
* 4. Checks if URL is already correct before failing
|
|
25
|
+
*/
|
|
26
|
+
export declare function safeWaitForURL(page: Page, urlPattern: string | RegExp | ((url: URL) => boolean), options?: SafeWaitForURLOptions): Promise<void>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Locator, Page } from '@playwright/test';
|
|
2
|
+
import type { RuleObject } from 'axe-core';
|
|
3
|
+
/**
|
|
4
|
+
* Wait for a page to be fully ready (DOM complete + brief delay for lazy rendering)
|
|
5
|
+
*/
|
|
6
|
+
export declare function waitForPageReady(page: Page, timeout?: number): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Check if the current user is an admin by reading localStorage
|
|
9
|
+
*/
|
|
10
|
+
export declare function checkAdminStatus(page: Page): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Wait for an element to be fully stable (attached, visible, not animating)
|
|
13
|
+
*/
|
|
14
|
+
export declare function waitForElementStable(page: Page, locator: Locator, timeout?: number): Promise<Locator>;
|
|
15
|
+
/**
|
|
16
|
+
* Click an element with retry logic and stability checks
|
|
17
|
+
*/
|
|
18
|
+
export declare function reliableClick(page: Page, locator: Locator, timeout?: number, maxRetries?: number): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Fill an input element with retry logic, clearing first and verifying the value
|
|
21
|
+
*/
|
|
22
|
+
export declare function reliableFill(page: Page, locator: Locator, value: string, timeout?: number, maxRetries?: number): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Wait for a dialog element to be visible and its content loaded
|
|
25
|
+
*/
|
|
26
|
+
export declare function waitForDialogReady(page: Page, dialogLocator: Locator, timeout?: number): Promise<Locator>;
|
|
27
|
+
/**
|
|
28
|
+
* Select a date from a calendar component, navigating months if needed
|
|
29
|
+
*/
|
|
30
|
+
export declare function selectDateFromCalendar(page: Page, dialogLocator: Locator, targetDate: Date, timeout?: number): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Run axe-core accessibility checks against a page
|
|
33
|
+
*/
|
|
34
|
+
export declare function expectNoAccessibilityViolations(page: Page): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Run axe-core accessibility checks against visible dialogs
|
|
37
|
+
*/
|
|
38
|
+
export declare function expectNoAccessibilityViolationsOnDialogs(page: Page, rules?: RuleObject, exclude?: string[]): Promise<void>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type PlaywrightTestConfig } from '@playwright/test';
|
|
2
|
+
export interface PlatformConfig {
|
|
3
|
+
/** Platform name used in project naming (e.g., 'mentornextjs', 'skills') */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Devices to test on. Defaults to all 4 desktop browsers */
|
|
6
|
+
devices?: string[];
|
|
7
|
+
/** Dependencies for this platform (e.g., ['setup']) */
|
|
8
|
+
dependencies?: string[];
|
|
9
|
+
/** Additional test file patterns to match */
|
|
10
|
+
otherTestMatch?: string[];
|
|
11
|
+
/** Test files to ignore */
|
|
12
|
+
testIgnore?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface CreatePlaywrightConfigOptions {
|
|
15
|
+
/** Directory containing test files (relative to config file) */
|
|
16
|
+
testDir?: string;
|
|
17
|
+
/** Devices to use across all platforms. Defaults to Chrome, Firefox, Safari, Edge */
|
|
18
|
+
devices?: string[];
|
|
19
|
+
/** Platform configurations */
|
|
20
|
+
platforms: PlatformConfig[];
|
|
21
|
+
/** Path to custom reporter module (relative to config file). Defaults to './custom-reporter' */
|
|
22
|
+
customReporterPath?: string;
|
|
23
|
+
/** Additional cleanup or post-test projects */
|
|
24
|
+
extraProjects?: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
devices?: string[];
|
|
27
|
+
dependencies: string[];
|
|
28
|
+
testMatch: string[];
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/** Extract browser key from device name (e.g., 'Desktop Chrome' -> 'chrome') */
|
|
32
|
+
export declare function getBrowserKey(deviceName: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Generate per-browser setup projects for Playwright authentication.
|
|
35
|
+
* Each browser gets its own auth setup project (setup-chrome, setup-firefox, etc.)
|
|
36
|
+
*/
|
|
37
|
+
export declare function generateBrowserSetupProjects(devicesToUse: string[]): {
|
|
38
|
+
name: string;
|
|
39
|
+
testMatch: RegExp;
|
|
40
|
+
use: {
|
|
41
|
+
viewport: import("@playwright/test").ViewportSize;
|
|
42
|
+
userAgent: string;
|
|
43
|
+
deviceScaleFactor: number;
|
|
44
|
+
isMobile: boolean;
|
|
45
|
+
hasTouch: boolean;
|
|
46
|
+
defaultBrowserType: "chromium" | "firefox" | "webkit";
|
|
47
|
+
};
|
|
48
|
+
}[];
|
|
49
|
+
/**
|
|
50
|
+
* Generate a Playwright project config for a platform + device combination.
|
|
51
|
+
*/
|
|
52
|
+
export declare function generateProjectConfig(platform: string, deviceName: string, dependencies?: string[], otherTestMatch?: string[], testIgnoreMatch?: string[]): {
|
|
53
|
+
name: string;
|
|
54
|
+
testMatch: string[];
|
|
55
|
+
use: {
|
|
56
|
+
storageState: string;
|
|
57
|
+
viewport: import("@playwright/test").ViewportSize;
|
|
58
|
+
userAgent: string;
|
|
59
|
+
deviceScaleFactor: number;
|
|
60
|
+
isMobile: boolean;
|
|
61
|
+
hasTouch: boolean;
|
|
62
|
+
defaultBrowserType: "chromium" | "firefox" | "webkit";
|
|
63
|
+
};
|
|
64
|
+
dependencies: string[];
|
|
65
|
+
testIgnore: string[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Create a complete Playwright configuration for an IBL.ai application.
|
|
69
|
+
*
|
|
70
|
+
* Usage:
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { createPlaywrightConfig } from '@iblai/iblai-js/playwright';
|
|
73
|
+
*
|
|
74
|
+
* export default createPlaywrightConfig({
|
|
75
|
+
* platforms: [
|
|
76
|
+
* { name: 'skills', dependencies: ['setup'], otherTestMatch: ['**skills/*\/*.spec.ts'] },
|
|
77
|
+
* ],
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function createPlaywrightConfig(options: CreatePlaywrightConfigOptions): PlaywrightTestConfig;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Locator, Page } from '@playwright/test';
|
|
2
|
+
/**
|
|
3
|
+
* Privacy tab helpers — Playwright bindings for the `AgentPrivacyTab`
|
|
4
|
+
* component from `@iblai/web-containers`.
|
|
5
|
+
*
|
|
6
|
+
* All UI strings below mirror `AGENT_PRIVACY_TAB_LABELS` from
|
|
7
|
+
* `@iblai/web-containers/next`. If a consumer renames a label via the
|
|
8
|
+
* `labels` prop, override these constants per spec — don't edit this file.
|
|
9
|
+
*
|
|
10
|
+
* The helpers assume the Edit Mentor dialog is already open. Call
|
|
11
|
+
* `switchToPrivacyTab(page)` first; from then on, every helper accepts
|
|
12
|
+
* either the `Page` or the dialog `Locator`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PRIVACY_LABELS: {
|
|
15
|
+
readonly tabName: "Privacy";
|
|
16
|
+
readonly headerTitle: "Privacy";
|
|
17
|
+
readonly actionLabel: "When PII is detected";
|
|
18
|
+
readonly blockMessageLabel: "Block Message";
|
|
19
|
+
readonly entitiesLabel: "Entity Types";
|
|
20
|
+
readonly outputFilterLabel: "Also filter AI responses";
|
|
21
|
+
readonly entitiesEmptyHint: "Using defaults.";
|
|
22
|
+
readonly actionOptions: {
|
|
23
|
+
readonly redact: "Redact";
|
|
24
|
+
readonly mask: "Mask";
|
|
25
|
+
readonly block: "Block";
|
|
26
|
+
};
|
|
27
|
+
readonly entityChips: {
|
|
28
|
+
readonly PERSON: "Person";
|
|
29
|
+
readonly EMAIL_ADDRESS: "Email";
|
|
30
|
+
readonly PHONE_NUMBER: "Phone";
|
|
31
|
+
readonly US_SSN: "SSN";
|
|
32
|
+
readonly CREDIT_CARD: "Credit Card";
|
|
33
|
+
readonly LOCATION: "Location";
|
|
34
|
+
readonly DATE_TIME: "Date / Time";
|
|
35
|
+
readonly US_PASSPORT: "Passport";
|
|
36
|
+
readonly US_DRIVER_LICENSE: "Driver's License";
|
|
37
|
+
readonly IP_ADDRESS: "IP Address";
|
|
38
|
+
readonly IBAN_CODE: "IBAN";
|
|
39
|
+
readonly MEDICAL_LICENSE: "Medical License";
|
|
40
|
+
readonly US_BANK_NUMBER: "Bank Number";
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export type PrivacyAction = keyof typeof PRIVACY_LABELS.actionOptions;
|
|
44
|
+
export type PrivacyEntity = keyof typeof PRIVACY_LABELS.entityChips;
|
|
45
|
+
/**
|
|
46
|
+
* Check whether the Privacy tab is currently rendered in the Edit Mentor
|
|
47
|
+
* dialog. Returns false instead of throwing so consumers can guard
|
|
48
|
+
* conditionally rendered tabs.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isPrivacyTabVisible(page: Page): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Switch to the Privacy tab. Assumes the Edit Mentor dialog is open.
|
|
53
|
+
*
|
|
54
|
+
* The Privacy Router on/off toggle lives on the Settings tab — this tab
|
|
55
|
+
* only shows dependent PII-handling fields when the router is enabled.
|
|
56
|
+
* Confirm landing via the tab body's testid rather than any inner label,
|
|
57
|
+
* since the field labels are conditional.
|
|
58
|
+
*/
|
|
59
|
+
export declare function switchToPrivacyTab(page: Page): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Assert that all dependent privacy fields are hidden — the case when the
|
|
62
|
+
* Privacy Router is disabled (on the Settings tab).
|
|
63
|
+
*/
|
|
64
|
+
export declare function expectPrivacyFieldsHidden(scope: Page | Locator): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Assert that the action selector, entities, and output filter are visible —
|
|
67
|
+
* the case when the master toggle is on.
|
|
68
|
+
*/
|
|
69
|
+
export declare function expectPrivacyFieldsVisible(scope: Page | Locator): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Pick a value in the "When PII is detected" select. The block-message
|
|
72
|
+
* textarea will appear / disappear automatically based on the selection.
|
|
73
|
+
*/
|
|
74
|
+
export declare function selectPrivacyAction(scope: Page | Locator, action: PrivacyAction): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Type a custom block message and commit it. The field saves on blur, so
|
|
77
|
+
* this helper blurs the textarea after typing.
|
|
78
|
+
*/
|
|
79
|
+
export declare function setBlockMessage(scope: Page | Locator, text: string): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Locator for a single entity chip. Chips are buttons with
|
|
82
|
+
* `role="checkbox"` and an `aria-label` matching the user-facing chip text.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getEntityChip(scope: Page | Locator, entity: PrivacyEntity): Locator;
|
|
85
|
+
/**
|
|
86
|
+
* Toggle an entity chip until it matches the desired selected state.
|
|
87
|
+
*/
|
|
88
|
+
export declare function setEntitySelected(scope: Page | Locator, entity: PrivacyEntity, selected: boolean): Promise<void>;
|
|
89
|
+
export declare function expectEntitySelected(scope: Page | Locator, entity: PrivacyEntity, selected: boolean): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Locator for the "Also filter AI responses" switch.
|
|
92
|
+
*/
|
|
93
|
+
export declare function getOutputFilterSwitch(scope: Page | Locator): Locator;
|
|
94
|
+
export declare function setOutputFilterEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;
|
|
95
|
+
export declare function expectOutputFilterEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;
|