import * as _playwright_test from '@playwright/test';
import { Page, Locator, PlaywrightTestConfig } from '@playwright/test';
export { expect } from '@playwright/test';
import winston from 'winston';
import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
import { RuleObject } from 'axe-core';
import * as playwright_core from 'playwright-core';

interface SafeWaitForURLOptions {
    timeout?: number;
    waitUntil?: 'commit' | 'domcontentloaded' | 'load' | 'networkidle';
    maxRetries?: number;
}
/**
 * Check if the current browser is Firefox
 */
declare function isFirefox(page: Page): boolean;
/**
 * Safe wrapper around page.waitForURL that handles browser-specific navigation errors
 *
 * Firefox has stricter navigation lifecycle handling that can cause NS_BINDING_ABORTED
 * errors when multiple rapid navigations occur (React router redirects, auth redirects).
 *
 * Safari can throw "Navigation canceled by policy check" errors during cross-origin
 * navigations or when security policies interrupt the navigation flow.
 *
 * This utility:
 * 1. Uses `waitUntil: 'commit'` for Firefox (faster, avoids abort)
 * 2. Includes retry logic for NS_BINDING_ABORTED errors (Firefox)
 * 3. Handles "Navigation canceled by policy check" errors (Safari)
 * 4. Checks if URL is already correct before failing
 */
declare function safeWaitForURL(page: Page, urlPattern: string | RegExp | ((url: URL) => boolean), options?: SafeWaitForURLOptions): Promise<void>;

declare function waitForPageLoad(page: Page): Promise<void>;
declare function closeWithEsc(page: Page): Promise<void>;
type StepFn = (title: string, fn: () => unknown) => unknown;
declare const test: _playwright_test.TestType<_playwright_test.PlaywrightTestArgs & _playwright_test.PlaywrightTestOptions & {
    step: StepFn;
}, _playwright_test.PlaywrightWorkerArgs & _playwright_test.PlaywrightWorkerOptions>;
declare const retry: (action: () => Promise<void>, errorMessage: string, retryCount?: number) => Promise<void>;

declare const isJSON: (value: string) => boolean;

declare const logger: winston.Logger;

interface MailsacEmail {
    _id: string;
    from: Array<{
        address: string;
        name?: string;
    }>;
    to: Array<{
        address: string;
        name?: string;
    }>;
    subject: string;
    inbox: string;
    received: string;
    size: number;
    attachments: string[];
    ip: string;
    via: string;
    folder: string;
    labels: string[];
    read: boolean;
    rtls: boolean;
    originalInbox: string;
    spam: boolean;
}
declare class MailsacClient {
    private apiKey;
    private baseUrl;
    constructor(apiKey: string);
    /**
     * Get all emails for a specific inbox
     * @param inbox - The inbox address (e.g., 'test@mailsac.com' or just 'test')
     */
    getEmails(inbox: string): Promise<MailsacEmail[]>;
    /**
     * Get a specific email by ID
     * @param email - The email address
     * @param messageId - The ID of the email to fetch
     */
    getEmailById(email: string, messageId: string): Promise<string>;
    /**
     * Delete a specific email by ID
     * @param emailId - The ID of the email to delete
     */
    deleteEmail(emailId: string): Promise<any>;
}

declare class AuthFlowBuilder {
    flow: string;
    idp: string;
    authHost: string;
    constructor(flow?: string, idp?: string, authHost?: string);
    run(page: Page, step: StepFn, username: string, password: string, hostUrl: string, authUrl: string, postLoginUrlMatcher?: (url: URL) => boolean): Promise<void>;
    usernamePasswordFlow(page: Page, username: string, password: string, hostUrl: string, authUrl: string, postLoginUrlMatcher?: (url: URL) => boolean): Promise<void>;
    magicLinkFlow(page: Page): Promise<void>;
    ssoFlow(page: Page, username: string, password: string, hostUrl: string, authUrl: string): Promise<void>;
    directSsoFlow(page: Page, step: StepFn, username: string, password: string, hostUrl: string, authUrl: string): Promise<void>;
}

interface SignUpCredentials {
    email: string;
    password: string;
}
declare function signUpWithEmailAndPassword(page: Page, authHost: string, postSignUpUrl: string, credentials?: SignUpCredentials, alreadyInSignupPage?: boolean): Promise<void>;
declare function loginWithEmailAndPassword(page: Page, username: string, password: string, hostUrl: string, postLoginUrlMatcher?: (url: URL) => boolean): Promise<void>;
declare function loginWithMicrosoftIdp(page: Page, username: string, password: string): Promise<void>;
declare function canChatWithEmbedMentor(page: Page, openChatButton: Locator): Promise<void>;
declare function getMentorIdFromUrl(url: string): string | null;

interface AuthSetupConfig {
    /** The app's host URL (e.g., https://mentor.example.com) */
    hostUrl: string;
    /** The auth service host URL (e.g., https://auth.example.com) */
    authHost: string;
    /** App name used in the login redirect URL (e.g., 'mentor', 'skills') */
    appName: string;
    /** Function to match the post-login URL to confirm authentication succeeded */
    postLoginUrlMatcher: (url: URL) => boolean;
    /** Auth flow type. Defaults to reading AUTH_FLOW env var or 'username_password' */
    authFlow?: 'username_password' | 'magic_link' | 'sso' | 'direct_sso';
    /** Auth IDP name for SSO flows */
    authIdp?: string;
}
/**
 * Creates a Playwright setup test function for authentication.
 * Use this as the test body in your auth.setup.ts file:
 *
 * ```ts
 * import { test as setup } from '@iblai/iblai-js/playwright';
 * import { createAuthSetup } from '@iblai/iblai-js/playwright';
 *
 * setup('authenticate', createAuthSetup({
 *   hostUrl: process.env.MENTOR_NEXTJS_HOST || '',
 *   authHost: process.env.AUTH_HOST || '',
 *   appName: 'mentor',
 *   postLoginUrlMatcher: (url) => url.href.includes('/platform/'),
 * }));
 * ```
 */
declare function createAuthSetup(config: AuthSetupConfig): ({ browser, step }: {
    browser: any;
    step: any;
}, testInfo: any) => Promise<void>;

declare class CustomReporter implements Reporter {
    onBegin(config: FullConfig, suite: Suite): void;
    onTestBegin(test: TestCase): void;
    onTestEnd(test: TestCase, result: TestResult): void;
    onTimeout(timeout: number): void;
    onEnd(result: FullResult): Promise<{
        status?: FullResult['status'];
    } | undefined | void> | void;
    onStdOut(chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void;
    onStdErr(chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void;
}

/**
 * Wait for a page to be fully ready (DOM complete + brief delay for lazy rendering)
 */
declare function waitForPageReady(page: Page, timeout?: number): Promise<void>;
/**
 * Check if the current user is an admin by reading localStorage
 */
declare function checkAdminStatus(page: Page): Promise<boolean>;
/**
 * Wait for an element to be fully stable (attached, visible, not animating)
 */
declare function waitForElementStable(page: Page, locator: Locator, timeout?: number): Promise<Locator>;
/**
 * Click an element with retry logic and stability checks
 */
declare function reliableClick(page: Page, locator: Locator, timeout?: number, maxRetries?: number): Promise<void>;
/**
 * Fill an input element with retry logic, clearing first and verifying the value
 */
declare function reliableFill(page: Page, locator: Locator, value: string, timeout?: number, maxRetries?: number): Promise<void>;
/**
 * Wait for a dialog element to be visible and its content loaded
 */
declare function waitForDialogReady(page: Page, dialogLocator: Locator, timeout?: number): Promise<Locator>;
/**
 * Select a date from a calendar component, navigating months if needed
 */
declare function selectDateFromCalendar(page: Page, dialogLocator: Locator, targetDate: Date, timeout?: number): Promise<void>;
/**
 * Run axe-core accessibility checks against a page
 */
declare function expectNoAccessibilityViolations(page: Page): Promise<void>;
/**
 * Run axe-core accessibility checks against visible dialogs
 */
declare function expectNoAccessibilityViolationsOnDialogs(page: Page, rules?: RuleObject, exclude?: string[]): Promise<void>;

declare function inviteUserTest(page: Page, inviteModal: Locator): Promise<void>;
declare function navigateToAccountComponent(page: Page, profileBtn: Locator): Promise<Locator>;
declare function navigateToDataReports(page: Page): Promise<void>;
declare function shouldDisplayReportCards(page: Page, REPORT_CARDS: {
    name: string;
    ariaLabel: string;
    description: string;
    expectsCsvEditor: boolean;
}[]): Promise<void>;
declare function shouldOpenCSVEditorDialog(page: Page): Promise<void>;
declare function shouldDisplayCSVInEditableTableFormat(page: Page): Promise<void>;
declare function shouldAllowEditingCellValuesInCSVEditor(page: Page): Promise<void>;
declare function shouldAddNewRowWhenClickingAddRowButton(page: Page): Promise<void>;
declare function shouldSaveEditedCSVAndTriggerDownload(page: Page): Promise<void>;
declare function shouldCloseCSVEditorWithoutSavingWhenClickingCancel(page: Page): Promise<void>;
declare function shouldCloseCSVEditorWhenClickingCloseButton(page: Page): Promise<void>;
declare function shouldVerifyCSVEditorDialogAccessibility(page: Page): Promise<void>;
declare function shouldOpenCSVEditorForUserMetadataReport(page: Page): Promise<void>;
declare function shouldDirectlyDownloadChatHistoryReportWithoutCSVEditor(page: Page): Promise<void>;
declare function shouldDisableOtherDownloadButtonsWhileGeneratingReport(page: Page): Promise<void>;
declare function shouldShowCombiningReportsDialog(page: Page): Promise<void>;
declare function shouldCancelCombiningReports(page: Page): Promise<void>;
declare function shouldHaveCombinedReportDataTestIds(page: Page): Promise<void>;
declare function shouldCombineRecommendationReports(page: Page): Promise<void>;

type AuthFlowType = 'username_password' | 'magic_link' | 'sso' | 'direct_sso';
interface EnvConfig {
    skillHost: string;
    authHost: string;
    analyticsHost: string;
    mentorHost: string;
    mentorNextjsHost: string;
    authNextjsHost: string;
    playwrightUsername: string;
    playwrightPassword: string;
    inviteUsername: string;
    inviteUserPassword: string;
    authFlow: AuthFlowType;
    authIdp: string;
    enableStripeTest: boolean;
    iblMentorDisabledTabs: string;
    embedUrl: string;
    wcagRange: string;
}
/**
 * Create an environment configuration object from process.env with optional overrides.
 * Each app can call this with their specific defaults.
 */
declare function createEnvConfig(overrides?: Partial<EnvConfig>): EnvConfig;

interface ReportDownloadOptions {
    /** Base URL of the SPA (e.g. https://mentor.ibl.ai) */
    baseUrl: string;
    /** Platform key extracted from or expected in the URL */
    platformKey: string;
    /** Report name extracted from or expected in the URL */
    reportName: string;
    /** Timeout for waiting on phase transitions (default: 60000ms) */
    timeout?: number;
}
/**
 * Build the expected report download page URL.
 * Format: <baseUrl>/reports/<platformKey>/<reportName>
 */
declare function buildReportUrl(baseUrl: string, platformKey: string, reportName: string): string;
/**
 * Parse platform_key and report_name from the current page URL.
 * Expected format: .../reports/<platform_key>/<report_name>
 */
declare function parseReportUrlParams(url: string): {
    platformKey: string;
    reportName: string;
} | null;
/**
 * Navigate to the report download page and verify the URL matches the expected format.
 */
declare function navigateToReportDownload(page: Page, options: ReportDownloadOptions): Promise<void>;
/**
 * Verify the report download page is showing the "Preparing" phase.
 */
declare function verifyPreparingPhase(page: Page, options?: {
    timeout?: number;
}): Promise<void>;
/**
 * Wait for and verify the report transitions to the "downloading" phase.
 */
declare function verifyDownloadingPhase(page: Page, options?: {
    timeout?: number;
}): Promise<void>;
/**
 * Wait for and verify the report transitions to the "done" phase.
 */
declare function verifyDonePhase(page: Page, options?: {
    timeout?: number;
}): Promise<void>;
/**
 * Wait for and verify the report transitions to the "error" phase.
 */
declare function verifyErrorPhase(page: Page, options?: {
    timeout?: number;
}): Promise<void>;
/**
 * Verify the "Back Home" button is visible and click it.
 */
declare function clickBackHome(page: Page): Promise<void>;
/**
 * Click the "Download Again" button (only visible in done phase).
 * Skips silently if the button is not visible.
 */
declare function clickDownloadAgain(page: Page): Promise<boolean>;
/**
 * Click the manual download link (only visible in downloading phase).
 */
declare function clickManualDownloadLink(page: Page): Promise<void>;
/**
 * Full flow: navigate to report download page and wait for download to complete.
 * Falls back to verifying the error phase if the download does not succeed.
 * Returns the resulting phase: 'done' or 'error'.
 */
declare function waitForReportDownload(page: Page, options: ReportDownloadOptions): Promise<'done' | 'error'>;

/**
 * Check if the Memory tab is visible in the profile modal.
 * Returns true if the tab exists and is visible, false otherwise.
 */
declare function isMemoryTabVisible(page: Page): Promise<boolean>;
/**
 * Switch to the Memory tab in the profile modal.
 * Assumes the profile modal is already open and the Memory tab is visible.
 */
declare function switchToMemoryTab(page: Page): Promise<void>;
/**
 * Verify that Memory tab settings section is visible with both toggles.
 */
declare function verifyMemoryTabSettings(page: Page): Promise<void>;
/**
 * Verify that the "My Memories" section is visible with Add Memory button.
 */
declare function verifyMemoryTabMemoriesList(page: Page): Promise<void>;
/**
 * Open the Add Memory dialog from the Memory tab.
 * Assumes the Memory tab is active.
 */
declare function openAddMemoryDialog(page: Page): Promise<Locator>;
/**
 * Toggle a memory setting switch and verify the state changes.
 * Returns the new checked state.
 */
declare function toggleMemorySwitch(page: Page, switchName: RegExp | string): Promise<boolean>;
/**
 * Add a memory via the Add Memory dialog.
 * Opens the dialog, fills content, saves, and waits for dialog to close.
 */
declare function addMemory(page: Page, content: string): Promise<void>;
/**
 * Delete the first visible memory in the list.
 * Hovers to reveal the delete button, then clicks it.
 */
declare function deleteFirstMemory(page: Page): Promise<void>;
/**
 * Delete a specific memory by matching its content text.
 * Finds the memory item containing the text, hovers to reveal
 * the delete button, and clicks it.
 */
declare function deleteMemoryByContent(page: Page, content: string): Promise<void>;
/**
 * @deprecated Use `deleteFirstMemory` instead. Archive was renamed to Delete.
 */
declare const archiveFirstMemory: typeof deleteFirstMemory;
/**
 * @deprecated Use `deleteMemoryByContent` instead. Archive was renamed to Delete.
 */
declare const archiveMemoryByContent: typeof deleteMemoryByContent;
/**
 * Get the count of visible memory items in the list.
 * Returns 0 if the empty state is shown.
 */
declare function getMemoryCount(page: Page): Promise<number>;
/**
 * Verify that a memory with the given content text exists in the list.
 */
declare function verifyMemoryExists(page: Page, content: string): Promise<void>;
/**
 * Verify that a memory with the given content text does NOT exist in the list.
 */
declare function verifyMemoryNotExists(page: Page, content: string): Promise<void>;

/**
 * Check if the Sandbox tab is visible in the edit-mentor modal.
 * Returns true if the tab exists and is visible (i.e. mentor has is_claw_enabled === true).
 */
declare function isSandboxTabVisible(page: Page): Promise<boolean>;
/**
 * Switch to the Sandbox tab inside the edit-mentor modal.
 * Assumes the modal is already open and the user has permission to see the tab.
 */
declare function switchToSandboxTab(page: Page): Promise<void>;
/**
 * Switch to the Skills tab inside the edit-mentor modal.
 */
declare function switchToSkillsTab(page: Page): Promise<void>;
/**
 * Verify the instance table is visible with all expected column headers.
 * Should be called when the mentor has no connected sandbox instance.
 */
declare function verifyInstanceTableVisible(page: Page): Promise<void>;
/**
 * Get the number of rows currently displayed in the instance table (excluding empty-state rows).
 */
declare function getInstanceRowCount(page: Page): Promise<number>;
/**
 * Verify the empty state is shown when there are no instances.
 */
declare function verifyInstanceTableEmpty(page: Page): Promise<void>;
/**
 * Filter the instance table by search query (name or URL).
 */
declare function searchInstances(page: Page, query: string): Promise<void>;
/**
 * Clear the instance table search query.
 */
declare function clearInstanceSearch(page: Page): Promise<void>;
/**
 * Open the Actions dropdown menu for a specific instance row.
 * Returns the dropdown menu locator.
 */
declare function openInstanceActionsMenu(page: Page, instanceName: string): Promise<Locator>;
/**
 * Open the "New Instance" dialog by clicking the Add Instance button.
 * Returns the dialog locator.
 */
declare function openNewInstanceDialog(page: Page): Promise<Locator>;
/**
 * Fill the New Instance form and submit it.
 * @param name - Display name for the instance
 * @param serverUrl - Fully qualified https URL
 * @param clawType - 'openclaw' (default) or 'ironclaw'
 * @param gatewayToken - Optional auth token
 */
declare function createInstance(page: Page, { name, serverUrl, clawType, gatewayToken, }: {
    name: string;
    serverUrl: string;
    clawType?: 'openclaw' | 'ironclaw';
    gatewayToken?: string;
}): Promise<void>;
/**
 * Cancel the New Instance dialog without submitting.
 */
declare function cancelNewInstanceDialog(page: Page): Promise<void>;
/**
 * Open the Edit dialog for an instance from its Actions menu.
 * Returns the edit dialog locator.
 */
declare function openEditInstanceDialog(page: Page, instanceName: string): Promise<Locator>;
/**
 * Edit an existing instance with new values.
 * @param instanceName - The current name of the instance to edit
 * @param updates - Fields to update
 */
declare function editInstance(page: Page, instanceName: string, updates: {
    name?: string;
    serverUrl?: string;
    clawType?: 'openclaw' | 'ironclaw';
}): Promise<void>;
/**
 * Delete an instance via the Actions menu, confirming the deletion dialog.
 */
declare function deleteInstance(page: Page, instanceName: string): Promise<void>;
/**
 * Open the delete confirmation dialog and cancel it without deleting.
 */
declare function cancelDeleteInstance(page: Page, instanceName: string): Promise<void>;
/**
 * Connect the current mentor to an instance via the Actions menu.
 */
declare function connectToInstance(page: Page, instanceName: string): Promise<void>;
/**
 * Disconnect the current mentor from its connected instance,
 * confirming the disconnect dialog.
 */
declare function disconnectInstance(page: Page): Promise<void>;
/**
 * Open the disconnect confirmation dialog and cancel it.
 */
declare function cancelDisconnectInstance(page: Page): Promise<void>;
/**
 * Open an instance's actions menu and click "Run checks". Resolves once the
 * health-check + connectivity-test toasts have surfaced (success or error).
 */
declare function runInstanceChecks(page: Page, instanceName: string): Promise<void>;
/**
 * Trigger the "Run checks" button on the connected-instance card. Used for the
 * connected-state flow rather than the table dropdown.
 */
declare function runConnectedInstanceChecks(page: Page): Promise<void>;
/**
 * Read the canonical health label rendered by `StatusDot` for the given row.
 * Returns "Healthy" / "Unhealthy" / null (em-dash for unknown).
 */
declare function getInstanceHealthLabel(page: Page, instanceName: string): Promise<'Healthy' | 'Unhealthy' | null>;
/**
 * Read the canonical status label rendered by `StatusDot` for the given row.
 * Returns "Active" / "Error" / null (em-dash for unknown).
 */
declare function getInstanceStatusLabel(page: Page, instanceName: string): Promise<'Active' | 'Error' | null>;
/**
 * Verify that the Connect dropdown item is blocked (dimmed + cursor-not-allowed)
 * because the instance status is unhealthy. Hovering should reveal the unhealthy
 * tooltip explaining why.
 */
declare function verifyConnectDisabledForUnhealthy(page: Page, instanceName: string): Promise<void>;
/**
 * Verify the Connected Instance card shows the expected fields.
 * The URL field shows the full server_url; other fields are status/health/last-check.
 */
declare function verifyConnectedInstanceCard(page: Page): Promise<void>;
/**
 * Toggle the Auto Push on Save switch.
 * Returns the new checked state.
 */
declare function toggleAutoPush(page: Page): Promise<boolean>;
/**
 * Click the Push button to push the current configuration to the worker.
 */
declare function pushConfiguration(page: Page): Promise<void>;
/**
 * Open the LLM provider picker by clicking Change (or Select Model) in the Model row.
 * Returns the picker dialog locator.
 */
declare function openLLMProviderPicker(page: Page): Promise<Locator>;
/**
 * Pick an LLM provider + model combination via the provider picker flow.
 * @param providerName - The provider key (e.g. 'anthropic', 'openai')
 * @param modelName - The model name (e.g. 'claude-sonnet-4-5-20250929')
 */
declare function selectLLMModel(page: Page, providerName: string, modelName: string): Promise<void>;
/**
 * Get the currently-selected model identifier shown next to the Model row.
 * Returns null if no model is set (button reads "Select Model").
 */
declare function getCurrentModel(page: Page): Promise<string | null>;
declare const AGENT_PROMPT_LABELS: readonly ["Identity", "Soul", "User Context", "Tools", "Agents", "Bootstrap", "Heartbeat", "Memory"];
type AgentPromptField = (typeof AGENT_PROMPT_LABELS)[number];
/**
 * Verify that all 8 agent config prompt fields are visible in the Prompts tab.
 * Only renders when the mentor has enable_claw === true on its settings.
 *
 * Note: PATCH on the agent-config endpoint is upsert — there's no separate
 * "Create Agent Config" button anymore. The first edit on any field bootstraps
 * the row.
 */
declare function verifyAgentConfigPromptsVisible(page: Page): Promise<void>;
/**
 * Open the edit modal for a specific agent prompt field (e.g. Identity, Soul).
 */
declare function openAgentPromptEditModal(page: Page, field: AgentPromptField): Promise<Locator>;
/**
 * Edit an agent prompt field (opens the modal, types content, saves).
 */
declare function editAgentPrompt(page: Page, field: AgentPromptField, content: string): Promise<void>;
/**
 * Verify the Skills tab content is loaded (either showing skill rows or the empty state).
 */
declare function verifySkillsTabVisible(page: Page): Promise<void>;
/**
 * Verify that the "No skills available" empty state is shown.
 */
declare function verifySkillsEmptyState(page: Page): Promise<void>;
/**
 * Count the number of skill rows rendered in the Skills tab.
 * Each row represents an available (enabled) platform skill.
 */
declare function getSkillRowCount(page: Page): Promise<number>;
/**
 * Verify that a specific skill row is visible in the Skills tab.
 */
declare function verifySkillVisible(page: Page, skillName: string): Promise<void>;
/**
 * Check if a specific skill is currently enabled for the mentor.
 */
declare function isSkillEnabled(page: Page, skillName: string): Promise<boolean>;
/**
 * Enable a skill for the current mentor by toggling it on.
 * No-op if already enabled. Waits for the success toast.
 */
declare function enableSkill(page: Page, skillName: string): Promise<void>;
/**
 * Disable a skill for the current mentor by toggling it off.
 * No-op if already disabled. Waits for the success toast.
 */
declare function disableSkill(page: Page, skillName: string): Promise<void>;
/**
 * Toggle a skill's enabled state (flips whatever the current state is).
 * Returns the new checked state.
 */
declare function toggleSkill(page: Page, skillName: string): Promise<boolean>;
interface SkillFormValues {
    name: string;
    slug: string;
    description?: string;
    version?: string;
    instruction?: string;
}
/**
 * Open the "New Skill" dialog by clicking the New Skill button in the Skills tab.
 * Returns the dialog locator.
 */
declare function openNewSkillDialog(page: Page): Promise<Locator>;
/**
 * Create a new platform-level skill via the Skills tab.
 */
declare function createSkill(page: Page, values: SkillFormValues): Promise<void>;
/**
 * Open the Actions dropdown for a specific skill row.
 * Returns the dropdown menu locator.
 */
declare function openSkillActionsMenu(page: Page, skillName: string): Promise<Locator>;
/**
 * Open the Edit Skill dialog from the actions menu.
 * Returns the dialog locator.
 */
declare function openEditSkillDialog(page: Page, skillName: string): Promise<Locator>;
/**
 * Edit an existing platform-level skill.
 * @param skillName - The current name of the skill to edit
 * @param updates - Fields to update on the skill
 */
declare function editSkill(page: Page, skillName: string, updates: Partial<SkillFormValues>): Promise<void>;
/**
 * Delete a platform-level skill, confirming the deletion dialog.
 */
declare function deleteSkill(page: Page, skillName: string): Promise<void>;
/**
 * Open the delete confirmation for a skill and cancel it (no deletion).
 */
declare function cancelDeleteSkill(page: Page, skillName: string): Promise<void>;
/**
 * Full workflow: open Sandbox tab, create a new instance, connect the mentor to it.
 * Returns when the mentor is successfully connected.
 */
declare function setupSandboxInstance(page: Page, instance: {
    name: string;
    serverUrl: string;
    clawType?: 'openclaw' | 'ironclaw';
    gatewayToken?: string;
}): Promise<void>;
/**
 * Full workflow: open Sandbox tab, disconnect the current instance (if any),
 * then delete it from the table.
 */
declare function teardownSandboxInstance(page: Page, instanceName: string): Promise<void>;

/**
 * Navigate to the Audit tab within the Analytics section.
 * Assumes the user is already on the analytics page (any tab).
 */
declare function navigateToAuditLog(page: Page): Promise<void>;
/**
 * Verify the audit log table is visible with correct headers.
 */
declare function verifyAuditLogTableVisible(page: Page): Promise<void>;
/**
 * Get the number of rows currently displayed in the audit log table.
 * Returns 0 if no table body rows are found.
 */
declare function getAuditLogRowCount(page: Page): Promise<number>;
/**
 * Verify that audit log entries contain expected data structure
 * (person name in first cell, action description in second, timestamp in third).
 */
declare function verifyAuditLogEntryStructure(page: Page): Promise<void>;
/**
 * Verify the empty state is displayed when there are no audit log entries.
 */
declare function verifyAuditLogEmptyState(page: Page): Promise<void>;
/**
 * Verify the 403 permission error state is displayed.
 */
declare function verifyAuditLogPermissionError(page: Page): Promise<void>;
/**
 * Verify the generic error state is displayed.
 */
declare function verifyAuditLogGenericError(page: Page): Promise<void>;
/**
 * Verify the loading spinner is displayed while audit logs are being fetched.
 */
declare function verifyAuditLogLoading(page: Page): Promise<void>;
/**
 * Wait for the audit log data to finish loading.
 * Waits for either table data, empty state, or error state to appear.
 */
declare function waitForAuditLogDataLoaded(page: Page, timeout?: number): Promise<void>;
/**
 * Filter audit log entries by action type.
 * @param action - One of 'All Actions', 'Create', 'Update', or 'Delete'
 */
declare function filterByAction(page: Page, action: 'All Actions' | 'Create' | 'Update' | 'Delete'): Promise<void>;
/**
 * Filter audit log entries by actor/person using the search combobox.
 * @param actorName - The username to filter by, or empty string to clear the filter
 */
declare function filterByActor(page: Page, actorName: string): Promise<void>;
/**
 * Get the list of actors available in the actor filter dropdown.
 * Opens the dropdown, reads the options, then closes it.
 */
declare function getAvailableActors(page: Page): Promise<string[]>;
/**
 * Open the date range picker and select a date range.
 * @param fromDate - Start date to select
 * @param toDate - End date to select
 */
declare function filterByDateRange(page: Page, fromDate: Date, toDate: Date): Promise<void>;
/**
 * Clear the date range filter by clicking the date picker and resetting.
 */
declare function clearDateRangeFilter(page: Page): Promise<void>;
/**
 * Get the current pagination info text (e.g., "Showing 1 to 20 of 45 results").
 * Returns null if pagination is not visible.
 */
declare function getPaginationInfo(page: Page): Promise<string | null>;
/**
 * Navigate to the next page of audit log results.
 */
declare function goToNextPage(page: Page): Promise<void>;
/**
 * Navigate to the previous page of audit log results.
 */
declare function goToPreviousPage(page: Page): Promise<void>;
/**
 * Navigate to the first page of audit log results.
 */
declare function goToFirstPage(page: Page): Promise<void>;
/**
 * Navigate to the last page of audit log results.
 * Finds the highest numbered page link in the pagination.
 */
declare function goToLastPage(page: Page): Promise<void>;
/**
 * Navigate to a specific page number by clicking its page button.
 */
declare function goToPage(page: Page, pageNumber: number): Promise<void>;
/**
 * Verify the current page is highlighted/active in pagination.
 */
declare function verifyCurrentPage(page: Page, expectedPage: number): Promise<void>;
/**
 * Check if the next page button is disabled (i.e., we're on the last page).
 */
declare function isOnLastPage(page: Page): Promise<boolean>;
/**
 * Check if the previous page button is disabled (i.e., we're on the first page).
 */
declare function isOnFirstPage(page: Page): Promise<boolean>;
/**
 * Full workflow: Navigate to audit log tab, wait for data to load,
 * and verify the table is visible. Use this as a test setup helper.
 */
declare function navigateToAuditLogAndWaitForData(page: Page): Promise<void>;
/**
 * Verify audit log entries are displayed after applying action filter.
 * Returns the row count after filtering.
 */
declare function filterByActionAndVerify(page: Page, action: 'All Actions' | 'Create' | 'Update' | 'Delete'): Promise<number>;
/**
 * Verify audit log entries are displayed after applying actor filter.
 * Returns the row count after filtering.
 */
declare function filterByActorAndVerify(page: Page, actorName: string): Promise<number>;

type CreditBalancePlan = 'Free' | 'Trial' | 'Premium';
/**
 * Reads `current_tenant` from localStorage and returns its `show_paywall` flag.
 * Returns false if the entry is missing, malformed, or the flag is unset.
 */
declare function getCurrentTenantShowPaywall(page: Page): Promise<boolean>;
/** Locator for the credit-balance trigger button (icon in the nav). */
declare function creditBalanceTrigger(page: Page): Locator;
/** Locator for the credit-balance dropdown panel (rendered in a Radix portal). */
declare function creditBalancePanel(page: Page): Locator;
/** Locator for the plan badge (Free / Trial / Premium) inside the open panel. */
declare function creditBalancePlanBadge(page: Page): Locator;
/**
 * Asserts the credit-balance trigger is visible iff the current tenant has
 * `show_paywall=true`. Returns the resolved expectation so callers can branch.
 */
declare function expectCreditBalanceVisibilityForTenant(page: Page): Promise<{
    shouldBeVisible: boolean;
}>;
/**
 * Opens the credit-balance dropdown if not already open, waits for the panel
 * to be visible, and waits for the initial "Loading credits..." placeholder to
 * clear so callers can immediately read content. Idempotent — safe to call
 * when the panel is already up.
 */
declare function openCreditBalanceDropdown(page: Page): Promise<Locator>;
/**
 * Waits for the "Loading credits..." placeholder to disappear from the open
 * panel. Resolves in the success path (real content rendered) or the error
 * path ("Unable to load credit balance." rendered) — both replace the loading
 * row. Returns immediately if the placeholder was never present.
 */
declare function waitForCreditBalanceLoaded(page: Page): Promise<void>;
/** Closes the credit-balance dropdown via Escape and waits for it to detach. */
declare function closeCreditBalanceDropdown(page: Page): Promise<void>;
/**
 * Reads the plan label text from the open panel. Returns null if the badge is
 * not rendered (e.g. billing data still loading or errored).
 */
declare function getCreditBalancePlanLabel(page: Page): Promise<CreditBalancePlan | null>;
/**
 * Reads the "Remaining" credits value from the open panel ("X,XXX Credits").
 * Returns null when the row is not rendered or unparseable.
 */
declare function getCreditBalanceRemaining(page: Page): Promise<number | null>;
/**
 * Free plan UI: Upgrade Plan only. No payment buttons. No auto-recharge section.
 */
declare function expectCreditBalancePanelForFreePlan(page: Page): Promise<void>;
/**
 * Trial plan UI: Upgrade Plan only. No Manage Usage / Add Credits / Manage Billing.
 */
declare function expectCreditBalancePanelForTrialPlan(page: Page): Promise<void>;
/**
 * Premium plan UI: Upgrade Plan must NOT appear.
 *  - With payment method: Manage Usage + Add Credits both visible; Manage Billing hidden.
 *  - Without payment method: Manage Billing visible; Manage Usage + Add Credits hidden.
 */
declare function expectCreditBalancePanelForPremiumPlan(page: Page, options: {
    hasPaymentMethod: boolean;
}): Promise<void>;
/**
 * Convenience: opens the dropdown, detects the active plan from the badge,
 * and runs the matching state assertions on the already-open panel. Returns
 * the detected plan label.
 *
 * For Premium plans you may pass `hasPaymentMethod` to assert the specific
 * sub-state; if omitted on Premium, only the "no Upgrade Plan button" check runs.
 */
declare function expectCreditBalanceForCurrentPlan(page: Page, options?: {
    hasPaymentMethod?: boolean;
}): Promise<CreditBalancePlan>;

/**
 * Privacy tab helpers — Playwright bindings for the `AgentPrivacyTab`
 * component from `@iblai/web-containers`.
 *
 * All UI strings below mirror `AGENT_PRIVACY_TAB_LABELS` from
 * `@iblai/web-containers/next`. If a consumer renames a label via the
 * `labels` prop, override these constants per spec — don't edit this file.
 *
 * The helpers assume the Edit Mentor dialog is already open. Call
 * `switchToPrivacyTab(page)` first; from then on, every helper accepts
 * either the `Page` or the dialog `Locator`.
 */
declare const PRIVACY_LABELS: {
    readonly tabName: "Privacy";
    readonly headerTitle: "Privacy";
    readonly routerLabel: "Enable Privacy Router";
    readonly actionLabel: "When PII is detected";
    readonly blockMessageLabel: "Block Message";
    readonly entitiesLabel: "Entity Types";
    readonly outputFilterLabel: "Also filter AI responses";
    readonly entitiesEmptyHint: "Using defaults.";
    readonly actionOptions: {
        readonly redact: "Redact";
        readonly mask: "Mask";
        readonly block: "Block";
    };
    readonly entityChips: {
        readonly PERSON: "Person";
        readonly EMAIL_ADDRESS: "Email";
        readonly PHONE_NUMBER: "Phone";
        readonly US_SSN: "SSN";
        readonly CREDIT_CARD: "Credit Card";
        readonly LOCATION: "Location";
        readonly DATE_TIME: "Date / Time";
        readonly US_PASSPORT: "Passport";
        readonly US_DRIVER_LICENSE: "Driver's License";
        readonly IP_ADDRESS: "IP Address";
        readonly IBAN_CODE: "IBAN";
        readonly MEDICAL_LICENSE: "Medical License";
        readonly US_BANK_NUMBER: "Bank Number";
    };
};
type PrivacyAction = keyof typeof PRIVACY_LABELS.actionOptions;
type PrivacyEntity = keyof typeof PRIVACY_LABELS.entityChips;
/**
 * Check whether the Privacy tab is currently rendered in the Edit Mentor
 * dialog. Returns false instead of throwing so consumers can guard
 * conditionally rendered tabs.
 */
declare function isPrivacyTabVisible(page: Page): Promise<boolean>;
/**
 * Switch to the Privacy tab. Assumes the Edit Mentor dialog is open.
 */
declare function switchToPrivacyTab(page: Page): Promise<void>;
/**
 * Locator for the master privacy-router switch.
 */
declare function getPrivacyRouterSwitch(scope: Page | Locator): Locator;
/**
 * Click the master toggle until it matches the desired state.
 */
declare function setPrivacyRouterEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;
declare function expectPrivacyRouterEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;
/**
 * Assert that all dependent privacy fields are hidden — the case when the
 * master toggle is off.
 */
declare function expectPrivacyFieldsHidden(scope: Page | Locator): Promise<void>;
/**
 * Assert that the action selector, entities, and output filter are visible —
 * the case when the master toggle is on.
 */
declare function expectPrivacyFieldsVisible(scope: Page | Locator): Promise<void>;
/**
 * Pick a value in the "When PII is detected" select. The block-message
 * textarea will appear / disappear automatically based on the selection.
 */
declare function selectPrivacyAction(scope: Page | Locator, action: PrivacyAction): Promise<void>;
/**
 * Type a custom block message and commit it. The field saves on blur, so
 * this helper blurs the textarea after typing.
 */
declare function setBlockMessage(scope: Page | Locator, text: string): Promise<void>;
/**
 * Locator for a single entity chip. Chips are buttons with
 * `role="checkbox"` and an `aria-label` matching the user-facing chip text.
 */
declare function getEntityChip(scope: Page | Locator, entity: PrivacyEntity): Locator;
/**
 * Toggle an entity chip until it matches the desired selected state.
 */
declare function setEntitySelected(scope: Page | Locator, entity: PrivacyEntity, selected: boolean): Promise<void>;
declare function expectEntitySelected(scope: Page | Locator, entity: PrivacyEntity, selected: boolean): Promise<void>;
/**
 * Locator for the "Also filter AI responses" switch.
 */
declare function getOutputFilterSwitch(scope: Page | Locator): Locator;
declare function setOutputFilterEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;
declare function expectOutputFilterEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;

/**
 * Voice tab helpers — Playwright bindings for the `AgentVoiceTab` component
 * from `@iblai/web-containers`.
 *
 * The Voice tab contains two sub-tabs:
 *   1. "Voice"              — provider + voice-picker, persisted via mentor settings
 *   2. "Call Configuration" — TTS / STT / LLM / video stack, persisted via the
 *                             `/call-configurations/` endpoint
 *
 * All UI strings mirror `AGENT_VOICE_TAB_LABELS` from
 * `@iblai/web-containers/next`. If a consumer renames a label via the
 * `labels` prop, override these constants per spec — don't edit this file.
 *
 * Selectors below use stable hooks only: `data-testid`, role + name, and
 * label-based queries. No CSS class selectors anywhere — the underlying
 * Tailwind classes are not part of the public contract.
 *
 * The helpers assume the Edit Mentor dialog is already open. Call
 * `switchToVoiceTab(page)` first; from then on every helper accepts either
 * the `Page` or the dialog `Locator`.
 */
declare const VOICE_LABELS: {
    readonly tabName: "Voice";
    readonly headerTitle: "Voice";
    readonly subTabs: {
        readonly voice: "Voice";
        readonly callConfig: "Voice call";
    };
    readonly providers: {
        readonly browser: "Browser";
        readonly openai: "OpenAI";
        readonly google: "Google";
    };
    readonly voicePickerLabel: {
        readonly openai: "OpenAI Voice";
        readonly google: "Google Voice";
    };
    readonly saveVoiceButton: RegExp;
    readonly callConfigSaveCreate: "Save";
    readonly callConfigSaveUpdate: "Save changes";
    readonly callConfigResetButton: "Reset";
    readonly callConfigFields: {
        readonly mode: "Call style";
        readonly language: "Spoken language";
        readonly llmProvider: "AI provider";
        readonly ttsProvider: "Text-to-speech provider";
        readonly sttProvider: "Speech-to-text provider";
        readonly useFunctionCalling: "Look things up only when needed";
        readonly enableVideo: "Allow screen sharing on a call";
    };
    readonly modeOptions: {
        readonly realtime: "Live conversation";
        readonly inference: "Step-by-step";
    };
    readonly ttsOptions: {
        readonly openai: "OpenAI";
        readonly google: "Google";
        readonly elevenlabs: "ElevenLabs";
    };
    readonly llmOptions: {
        readonly openai: "OpenAI";
        readonly google: "Google";
        readonly anthropic: "Anthropic";
    };
};
type VoiceProvider = keyof typeof VOICE_LABELS.providers;
type CallMode = keyof typeof VOICE_LABELS.modeOptions;
type TtsProvider = keyof typeof VOICE_LABELS.ttsOptions;
type SttProvider = TtsProvider;
type LlmProvider = keyof typeof VOICE_LABELS.llmOptions;
/**
 * Check whether the Voice tab is currently rendered in the Edit Mentor
 * dialog. Returns false instead of throwing so consumers can guard
 * conditionally rendered tabs.
 */
declare function isVoiceTabVisible(page: Page): Promise<boolean>;
/**
 * Switch to the Voice tab. Assumes the Edit Mentor dialog is open.
 */
declare function switchToVoiceTab(page: Page): Promise<void>;
/**
 * Switch between the Voice / Voice call sub-tabs.
 *
 * Note: "Screen share" used to live here as a third sub-tab but is now
 * a peer top-level tab in the edit-mentor modal. Use the helpers in
 * `screenshare-tab-helpers.ts` for it.
 */
declare function switchToVoiceSubTab(scope: Page | Locator, sub: 'voice' | 'callConfig'): Promise<void>;
/**
 * Locator for one of the three provider cards on the "Voice" sub-tab.
 */
declare function getVoiceProviderCard(scope: Page | Locator, provider: VoiceProvider): Locator;
/**
 * Click a provider card. The picker below changes shape based on the
 * selection (Browser → no picker; OpenAI / Google → searchable voice list).
 */
declare function selectVoiceProvider(scope: Page | Locator, provider: VoiceProvider): Promise<void>;
declare function expectVoiceProviderSelected(scope: Page | Locator, provider: VoiceProvider): Promise<void>;
/**
 * Open the modal voice picker for the active mentor-voice provider
 * (OpenAI or Google). The trigger renders the currently-picked voice on
 * the Voice sub-tab; clicking its "open" button opens a Dialog with
 * the searchable + paginated picker inside.
 *
 * The trigger root container exposes `data-testid="mentor-voice-trigger"`,
 * and the open button (inside it) is `mentor-voice-trigger-open`. The
 * inline play button is `mentor-voice-trigger-preview` — see
 * `previewMentorVoiceInline`.
 */
declare function openMentorVoicePicker(scope: Page | Locator): Promise<void>;
/**
 * Open the modal voice picker inside the Call Configuration sub-tab.
 * Only present when an LLM provider has been chosen.
 */
declare function openCallConfigVoicePicker(scope: Page | Locator): Promise<void>;
/**
 * Click the inline Play button on the mentor-voice trigger to preview
 * the currently-selected voice without opening the modal. Audio
 * playback isn't deterministically observable from Playwright, so this
 * just clicks and returns.
 */
declare function previewMentorVoiceInline(scope: Page | Locator): Promise<void>;
/**
 * Same as `previewMentorVoiceInline`, but for the Call Configuration
 * voice trigger.
 */
declare function previewCallConfigVoiceInline(scope: Page | Locator): Promise<void>;
/**
 * Assert that the trigger shows the given voice name (title-cased).
 * Useful for verifying that a previously-saved voice loads correctly.
 */
declare function expectMentorVoiceTriggerShows(scope: Page | Locator, voiceName: string): Promise<void>;
declare function expectCallConfigVoiceTriggerShows(scope: Page | Locator, voiceName: string): Promise<void>;
/**
 * Search the voice picker. Typing is debounced ~300ms inside the
 * component, so callers usually want to assert on the eventual results
 * (see `expectVoiceVisible`). When the picker lives inside the modal,
 * scope to the dialog: `searchVoices(page.getByTestId('voice-picker-modal'), 'al')`.
 *
 * Targets the input via `data-testid="voice-picker-search"` — a stable
 * hook that doesn't depend on the (overridable) placeholder copy and
 * avoids ReDoS-shaped placeholder regexes.
 */
declare function searchVoices(scope: Page | Locator, query: string): Promise<void>;
/**
 * Locator for an individual voice row in the picker. Rows are
 * `role="radio"` with `aria-label` matching the voice name.
 */
declare function getVoiceRow(scope: Page | Locator, voiceName: string): Locator;
declare function expectVoiceVisible(scope: Page | Locator, voiceName: string): Promise<void>;
/**
 * Click a voice row to select it. Returns once the row reports
 * aria-checked=true.
 */
declare function selectVoice(scope: Page | Locator, voiceName: string): Promise<void>;
/**
 * Click the inline preview button next to a voice. Returns immediately —
 * audio playback is async and not deterministically observable from
 * Playwright.
 */
declare function previewVoice(scope: Page | Locator, voiceName: string): Promise<void>;
/**
 * Click the Save button on the Voice sub-tab. Asserts the button is
 * enabled first (a no-op on a pristine form would be a test bug).
 */
declare function saveVoiceSettings(scope: Page | Locator): Promise<void>;
/**
 * Locator for the call configuration form, useful as a scope root for
 * subsequent helpers.
 */
declare function getCallConfigForm(scope: Page | Locator): Locator;
declare function expectCallConfigVisible(scope: Page | Locator): Promise<void>;
/**
 * Pick a call mode (realtime/inference). The TTS/STT selects below become
 * disabled in realtime mode — assert via `expectTtsSelectDisabled` if your
 * test cares.
 */
declare function selectCallMode(scope: Page | Locator, mode: CallMode): Promise<void>;
declare function setCallLanguage(scope: Page | Locator, code: string): Promise<void>;
declare function selectLlmProvider(scope: Page | Locator, provider: LlmProvider): Promise<void>;
declare function selectTtsProvider(scope: Page | Locator, provider: TtsProvider): Promise<void>;
declare function selectSttProvider(scope: Page | Locator, provider: SttProvider): Promise<void>;
declare function expectTtsSelectDisabled(scope: Page | Locator): Promise<void>;
declare function expectSttSelectDisabled(scope: Page | Locator): Promise<void>;
declare function setUseFunctionCallingEnabled(scope: Page | Locator, enabled: boolean): Promise<void>;
declare function setEnableVideo(scope: Page | Locator, enabled: boolean): Promise<void>;
/**
 * Click the call-config Save button. The label switches between
 * "Create configuration" and "Save changes" depending on whether a config
 * exists; we match either.
 */
declare function saveCallConfig(scope: Page | Locator): Promise<void>;
declare function resetCallConfig(scope: Page | Locator): Promise<void>;

/**
 * Screen share tab helpers — Playwright bindings for the standalone
 * `AgentScreenShareTab` component from `@iblai/web-containers`.
 *
 * The tab is a peer to Voice/LLM/Tools/etc in the edit-mentor modal.
 * It only edits the two screensharing prompts on the mentor's
 * CallConfiguration; the on/off toggle lives on the Settings tab.
 *
 * Selectors below use stable hooks only: `data-testid`, role + name,
 * and label-based queries. No CSS class selectors.
 */
declare const SCREENSHARE_LABELS: {
    readonly tabName: "Screen Share";
    readonly headerTitle: "Screen Share";
    readonly fields: {
        readonly systemPrompt: "Instructions during screen sharing";
        readonly proactivePrompt: "What the agent says when screen sharing starts";
    };
    readonly saveButton: "Save";
};
type ScreenSharePromptField = 'systemPrompt' | 'proactivePrompt';
/**
 * Returns false if the Screen share tab isn't currently rendered in
 * the Edit Mentor dialog (e.g. the host hasn't registered it, or it's
 * hidden by RBAC).
 */
declare function isScreenShareTabVisible(page: Page): Promise<boolean>;
/**
 * Switch to the Screen share top-level tab. Assumes the Edit Mentor
 * dialog is open.
 */
declare function switchToScreenShareTab(page: Page): Promise<void>;
/**
 * Open the inline prompt editor for one of the two screensharing
 * prompts. Mirrors the Prompts tab pattern: each prompt is rendered as
 * a card with an "Edit <label>" button that pops the rich-text modal.
 */
declare function openScreenSharePromptEditor(scope: Page | Locator, field: ScreenSharePromptField): Promise<void>;
/**
 * Replace the prompt text inside the rich-text modal and confirm. The
 * new value is written to local form state; call `saveScreenSharePrompts`
 * afterwards to persist.
 */
declare function setScreenSharePrompt(scope: Page | Locator, field: ScreenSharePromptField, text: string): Promise<void>;
/**
 * Click the tab's Save button to persist any pending prompt edits.
 * Asserts the button is enabled first — a no-op call on a pristine
 * tab would be a test bug.
 */
declare function saveScreenSharePrompts(scope: Page | Locator): Promise<void>;
/**
 * Assert whether the amber off-state hint is shown. The hint renders
 * when `enable_video` is false on the underlying CallConfiguration
 * (or when no call_configuration exists yet).
 */
declare function expectScreenShareDisabledHint(scope: Page | Locator, visible: boolean): Promise<void>;

type BillingAutoRechargeStatus = 'Enabled' | 'Disabled';
/** Locator for the Plan section card on the BillingTab. */
declare function billingPlanSection(page: Page): Locator;
/** Locator for the Credits section card on the BillingTab. */
declare function billingCreditsSection(page: Page): Locator;
/** Locator for the Auto Recharge section card on the BillingTab.
 *  This section is only rendered for non-Free plans with a payment method on file.
 */
declare function billingAutoRechargeSection(page: Page): Locator;
/** Reads the plan label (Free / Trial / Premium) from the Plan section. */
declare function getBillingPlanLabel(page: Page): Promise<CreditBalancePlan | null>;
/** Reads the auto-recharge status badge (Enabled / Disabled) when the section is rendered. */
declare function getBillingAutoRechargeStatus(page: Page): Promise<BillingAutoRechargeStatus | null>;
/** Waits for the BillingTab loading skeletons to clear by waiting for the Plan
 *  section card to mount. */
declare function waitForBillingTabReady(page: Page): Promise<void>;
/**
 * Asserts the Plan section state for a given plan. Verifies:
 *  - The plan label text matches `options.plan`
 *  - The "Current" pill is visible
 *  - The Upgrade button is visible iff the plan is not Premium
 */
declare function expectBillingPlanSection(page: Page, options: {
    plan: CreditBalancePlan;
}): Promise<void>;
/**
 * Asserts the Credits section state. Always verifies the "Available" stat row.
 * The action button rule mirrors the component:
 *   - Free plan → no Add Credits / Manage Billing button
 *   - Non-Free + hasPaymentMethod=true → "Add Credits" visible, "Manage Billing" absent
 *   - Non-Free + hasPaymentMethod=false → "Manage Billing" visible, "Add Credits" absent
 *   - Non-Free with hasPaymentMethod omitted → only the "Available" row is asserted
 */
declare function expectBillingCreditsSection(page: Page, options: {
    plan: CreditBalancePlan;
    hasPaymentMethod?: boolean;
}): Promise<void>;
/**
 * Asserts the Auto Recharge section visibility. Section is rendered only when
 * `hasPaymentMethod && !isFreePlan` in the component. Pass `expectVisible: false`
 * to assert the section is absent. When visible and `status` is provided, also
 * asserts the Enabled/Disabled badge text.
 */
declare function expectBillingAutoRechargeSection(page: Page, options: {
    expectVisible: boolean;
    status?: BillingAutoRechargeStatus;
}): Promise<void>;
/**
 * Free plan: Plan="Free" with Upgrade visible; Credits section has no action;
 * Auto Recharge section is hidden entirely (regardless of has_payment_method).
 */
declare function expectBillingTabForFreePlan(page: Page): Promise<void>;
/**
 * Trial plan: Plan="Trial" with Upgrade visible; Credits action depends on
 * `hasPaymentMethod` (Add Credits when true, Manage Billing when false);
 * Auto Recharge section is rendered iff `hasPaymentMethod` is true.
 */
declare function expectBillingTabForTrialPlan(page: Page, options: {
    hasPaymentMethod: boolean;
}): Promise<void>;
/**
 * Premium plan: Plan="Premium" with Upgrade hidden; Credits action depends on
 * `hasPaymentMethod` (Add Credits when true, Manage Billing when false);
 * Auto Recharge section is rendered iff `hasPaymentMethod` is true.
 */
declare function expectBillingTabForPremiumPlan(page: Page, options: {
    hasPaymentMethod: boolean;
}): Promise<void>;
/**
 * Convenience: detects the active plan from the Plan section badge and runs
 * the matching state assertions. Returns the detected plan.
 *
 * For non-Free plans, pass `hasPaymentMethod` to assert the Credits/Auto Recharge
 * sub-states; if omitted, only the Plan section + base Credits row is verified.
 */
declare function expectBillingTabForCurrentPlan(page: Page, options?: {
    hasPaymentMethod?: boolean;
}): Promise<CreditBalancePlan>;
/** Clicks the Upgrade button in the Plan section (visible only on non-Premium plans). */
declare function clickBillingUpgrade(page: Page): Promise<void>;
/** Clicks the Add Credits button in the Credits section (non-Free + has payment method). */
declare function clickBillingAddCredits(page: Page): Promise<void>;
/** Clicks the Manage Billing button in the Credits section (non-Free + no payment method). */
declare function clickBillingManageBilling(page: Page): Promise<void>;
/** Clicks the Manage Usage button in the Auto Recharge section. */
declare function clickBillingManageUsage(page: Page): Promise<void>;

/**
 * Tasks tab helpers — Playwright bindings for the `AgentTasksTab`
 * component from `@iblai/web-containers`.
 *
 * All UI strings below mirror `AGENT_TASKS_TAB_LABELS` from
 * `@iblai/web-containers/next`. If a consumer renames a label via the
 * `labels` prop, override these constants per spec — don't edit this file.
 *
 * The helpers assume the Edit Mentor dialog is already open. Call
 * `switchToTasksTab(page)` first; from then on, every helper accepts
 * either the `Page` or the dialog `Locator`.
 */
declare const TASKS_LABELS: {
    readonly tabName: "Tasks";
    readonly headerTitle: "Tasks";
    readonly headerDescription: "Configure automated tasks for your mentor.";
    readonly toolbar: {
        readonly searchPlaceholder: "Search all tasks...";
        readonly selectDate: "Select date";
        readonly scheduleTask: "Schedule Task";
    };
    readonly metrics: {
        readonly total: "Total Tasks";
        readonly completed: "Completed";
        readonly failed: "Failed";
    };
    /** Status badges displayed on each task row. */
    readonly status: {
        readonly completed: "Completed";
        readonly failed: "Failed";
        readonly running: "Running";
        readonly scheduled: "Scheduled";
        readonly disabled: "Disabled";
    };
    readonly list: {
        readonly selectHint: "Select a task to view its run logs.";
        readonly repeatOnce: "Once";
        readonly deleteTask: "Delete task";
    };
    readonly logs: {
        readonly title: "Task Logs";
        readonly selectPrompt: "Select a task on the left to view its run logs.";
        readonly noLogs: "No run logs for this task yet.";
        readonly loading: "Loading logs...";
        readonly forTask: "Logs for";
    };
    readonly states: {
        readonly loading: "Loading tasks...";
        readonly empty: "No tasks scheduled.";
    };
    readonly scheduleDialog: {
        readonly taskName: "Task Name";
        readonly taskNamePlaceholder: "Enter task name";
        readonly taskPrompt: "Task Prompt";
        readonly taskPromptPlaceholder: "Enter task prompt";
        readonly time: "Time";
        readonly repeat: "Repeat";
        readonly notifyByEmail: "Notify me by email";
        readonly schedule: "Schedule Task";
        readonly scheduling: "Scheduling...";
        readonly cancel: "Cancel";
        readonly dontRepeat: "Don't repeat";
        readonly daily: "Daily";
        readonly weekly: "Weekly";
        readonly monthly: "Monthly";
        readonly startTimeInPast: "Start time must be in the future.";
    };
    readonly deleteDialog: {
        readonly title: "Delete Task";
        readonly delete: "Delete Task";
        readonly deleting: "Deleting...";
        readonly cancel: "Cancel";
    };
    readonly logDetails: {
        readonly title: "Log Details";
        readonly status: "Status";
        readonly createdAt: "Created";
        readonly startTime: "Started";
        readonly endTime: "Ended";
        readonly output: "Output";
    };
};
/** The four repeat cadences accepted by `scheduleTask`. */
type TaskRepeat = "don't-repeat" | 'daily' | 'weekly' | 'monthly';
/** Possible status badges on a task row. */
type TaskStatus = keyof typeof TASKS_LABELS.status;
/**
 * Check whether the Tasks tab is currently rendered in the Edit Mentor
 * dialog. Returns false instead of throwing so callers can guard
 * conditionally rendered tabs (e.g. permission-gated).
 */
declare function isTasksTabVisible(page: Page): Promise<boolean>;
/**
 * Switch to the Tasks tab. Assumes the Edit Mentor dialog is open. After
 * the click we wait for the unique "Schedule Task" button before
 * returning, so callers can rely on the panel being interactive.
 */
declare function switchToTasksTab(page: Page): Promise<void>;
/** Locator for the "Schedule Task" toolbar button (opens the dialog). */
declare function getScheduleTaskButton(scope: Page | Locator): Locator;
/** Locator for the task list's search input. */
declare function getSearchInput(scope: Page | Locator): Locator;
/**
 * Locator for a task row by its title. We scope to the click-target
 * `role="button"` rendered by `TaskList` so callers can `.click()` to
 * select, or chain `.getByRole('button', { name: 'Delete task' })` to
 * delete.
 */
declare function getTaskRow(scope: Page | Locator, taskName: string): Locator;
declare function expectTotalTasks(scope: Page | Locator, n: number): Promise<void>;
declare function expectCompletedTasks(scope: Page | Locator, n: number): Promise<void>;
declare function expectFailedTasks(scope: Page | Locator, n: number): Promise<void>;
declare function expectTasksEmpty(scope: Page | Locator): Promise<void>;
declare function expectTaskInList(scope: Page | Locator, taskName: string): Promise<void>;
declare function expectTaskNotInList(scope: Page | Locator, taskName: string): Promise<void>;
/**
 * Click a task row to select it. Marks the row's `aria-pressed=true` and
 * the logs panel rebinds to that task.
 */
declare function selectTaskInList(scope: Page | Locator, taskName: string): Promise<void>;
/**
 * Assert that a given task's status badge matches the expected status.
 */
declare function expectTaskStatus(scope: Page | Locator, taskName: string, status: TaskStatus): Promise<void>;
/** Type into the search input. Returns once the input value matches. */
declare function searchTasks(scope: Page | Locator, query: string): Promise<void>;
/** Open the Schedule Task dialog and wait for it to be interactive. */
declare function openScheduleTaskDialog(scope: Page | Locator): Promise<void>;
/**
 * End-to-end: open the dialog, fill the form, click Schedule, and wait
 * for it to close.
 *
 * `time` is an HTML `<input type="time">` string ("HH:mm", 24-hour). If
 * the chosen date is today and the chosen time is in the past, the
 * dialog will block submission — choose accordingly.
 */
declare function scheduleTask(scope: Page | Locator, opts: {
    name: string;
    prompt?: string;
    time: string;
    repeat?: TaskRepeat;
    notifyByEmail?: boolean;
}): Promise<void>;
/** Asserts the in-dialog past-time error is currently shown. */
declare function expectScheduleStartTimeInPastError(scope: Page | Locator): Promise<void>;
/**
 * Click the trash icon on a task row and confirm the delete in the
 * follow-up dialog.
 */
declare function deleteTask(scope: Page | Locator, taskName: string): Promise<void>;
/**
 * Wait for the logs panel to finish loading and assert that the selected
 * task name is shown in the header.
 */
declare function expectLogsForTask(scope: Page | Locator, taskName: string): Promise<void>;
declare function expectNoLogsForSelectedTask(scope: Page | Locator): Promise<void>;
/**
 * Click the first log entry under the selected task to open the log
 * details modal. Returns once the dialog title is visible.
 */
declare function openFirstLogDetails(scope: Page | Locator): Promise<void>;
declare function expectLogDetailsStatus(scope: Page | Locator, status: 'success' | 'error' | 'running' | string): Promise<void>;

interface PlatformConfig {
    /** Platform name used in project naming (e.g., 'mentornextjs', 'skills') */
    name: string;
    /** Devices to test on. Defaults to all 4 desktop browsers */
    devices?: string[];
    /** Dependencies for this platform (e.g., ['setup']) */
    dependencies?: string[];
    /** Additional test file patterns to match */
    otherTestMatch?: string[];
    /** Test files to ignore */
    testIgnore?: string[];
}
interface CreatePlaywrightConfigOptions {
    /** Directory containing test files (relative to config file) */
    testDir?: string;
    /** Devices to use across all platforms. Defaults to Chrome, Firefox, Safari, Edge */
    devices?: string[];
    /** Platform configurations */
    platforms: PlatformConfig[];
    /** Path to custom reporter module (relative to config file). Defaults to './custom-reporter' */
    customReporterPath?: string;
    /** Additional cleanup or post-test projects */
    extraProjects?: Array<{
        name: string;
        devices?: string[];
        dependencies: string[];
        testMatch: string[];
    }>;
}
/** Extract browser key from device name (e.g., 'Desktop Chrome' -> 'chrome') */
declare function getBrowserKey(deviceName: string): string;
/**
 * Generate per-browser setup projects for Playwright authentication.
 * Each browser gets its own auth setup project (setup-chrome, setup-firefox, etc.)
 */
declare function generateBrowserSetupProjects(devicesToUse: string[]): {
    name: string;
    testMatch: RegExp;
    use: {
        viewport: playwright_core.ViewportSize;
        userAgent: string;
        deviceScaleFactor: number;
        isMobile: boolean;
        hasTouch: boolean;
        defaultBrowserType: "chromium" | "firefox" | "webkit";
    };
}[];
/**
 * Generate a Playwright project config for a platform + device combination.
 */
declare function generateProjectConfig(platform: string, deviceName: string, dependencies?: string[], otherTestMatch?: string[], testIgnoreMatch?: string[]): {
    name: string;
    testMatch: string[];
    use: {
        storageState: string;
        viewport: playwright_core.ViewportSize;
        userAgent: string;
        deviceScaleFactor: number;
        isMobile: boolean;
        hasTouch: boolean;
        defaultBrowserType: "chromium" | "firefox" | "webkit";
    };
    dependencies: string[];
    testIgnore: string[];
};
/**
 * Create a complete Playwright configuration for an IBL.ai application.
 *
 * Usage:
 * ```ts
 * import { createPlaywrightConfig } from '@iblai/iblai-js/playwright';
 *
 * export default createPlaywrightConfig({
 *   platforms: [
 *     { name: 'skills', dependencies: ['setup'], otherTestMatch: ['**skills/*\/*.spec.ts'] },
 *   ],
 * });
 * ```
 */
declare function createPlaywrightConfig(options: CreatePlaywrightConfigOptions): PlaywrightTestConfig;

export { AuthFlowBuilder, CustomReporter, MailsacClient, PRIVACY_LABELS, SCREENSHARE_LABELS, TASKS_LABELS, VOICE_LABELS, addMemory, archiveFirstMemory, archiveMemoryByContent, billingAutoRechargeSection, billingCreditsSection, billingPlanSection, buildReportUrl, canChatWithEmbedMentor, cancelDeleteInstance, cancelDeleteSkill, cancelDisconnectInstance, cancelNewInstanceDialog, checkAdminStatus, clearDateRangeFilter, clearInstanceSearch, clickBackHome, clickBillingAddCredits, clickBillingManageBilling, clickBillingManageUsage, clickBillingUpgrade, clickDownloadAgain, clickManualDownloadLink, closeCreditBalanceDropdown, closeWithEsc, connectToInstance, createAuthSetup, createEnvConfig, createInstance, createPlaywrightConfig, createSkill, creditBalancePanel, creditBalancePlanBadge, creditBalanceTrigger, deleteFirstMemory, deleteInstance, deleteMemoryByContent, deleteSkill, deleteTask, disableSkill, disconnectInstance, editAgentPrompt, editInstance, editSkill, enableSkill, expectBillingAutoRechargeSection, expectBillingCreditsSection, expectBillingPlanSection, expectBillingTabForCurrentPlan, expectBillingTabForFreePlan, expectBillingTabForPremiumPlan, expectBillingTabForTrialPlan, expectCallConfigVisible, expectCallConfigVoiceTriggerShows, expectCompletedTasks, expectCreditBalanceForCurrentPlan, expectCreditBalancePanelForFreePlan, expectCreditBalancePanelForPremiumPlan, expectCreditBalancePanelForTrialPlan, expectCreditBalanceVisibilityForTenant, expectEntitySelected, expectFailedTasks, expectLogDetailsStatus, expectLogsForTask, expectMentorVoiceTriggerShows, expectNoAccessibilityViolations, expectNoAccessibilityViolationsOnDialogs, expectNoLogsForSelectedTask, expectOutputFilterEnabled, expectPrivacyFieldsHidden, expectPrivacyFieldsVisible, expectPrivacyRouterEnabled, expectScheduleStartTimeInPastError, expectScreenShareDisabledHint, expectSttSelectDisabled, expectTaskInList, expectTaskNotInList, expectTaskStatus, expectTasksEmpty, expectTotalTasks, expectTtsSelectDisabled, expectVoiceProviderSelected, expectVoiceVisible, filterByAction, filterByActionAndVerify, filterByActor, filterByActorAndVerify, filterByDateRange, generateBrowserSetupProjects, generateProjectConfig, getAuditLogRowCount, getAvailableActors, getBillingAutoRechargeStatus, getBillingPlanLabel, getBrowserKey, getCallConfigForm, getCreditBalancePlanLabel, getCreditBalanceRemaining, getCurrentModel, getCurrentTenantShowPaywall, getEntityChip, getInstanceHealthLabel, getInstanceRowCount, getInstanceStatusLabel, getMemoryCount, getMentorIdFromUrl, getOutputFilterSwitch, getPaginationInfo, getPrivacyRouterSwitch, getScheduleTaskButton, getSearchInput, getSkillRowCount, getTaskRow, getVoiceProviderCard, getVoiceRow, goToFirstPage, goToLastPage, goToNextPage, goToPage, goToPreviousPage, inviteUserTest, isFirefox, isJSON, isMemoryTabVisible, isOnFirstPage, isOnLastPage, isPrivacyTabVisible, isSandboxTabVisible, isScreenShareTabVisible, isSkillEnabled, isTasksTabVisible, isVoiceTabVisible, logger, loginWithEmailAndPassword, loginWithMicrosoftIdp, navigateToAccountComponent, navigateToAuditLog, navigateToAuditLogAndWaitForData, navigateToDataReports, navigateToReportDownload, openAddMemoryDialog, openAgentPromptEditModal, openCallConfigVoicePicker, openCreditBalanceDropdown, openEditInstanceDialog, openEditSkillDialog, openFirstLogDetails, openInstanceActionsMenu, openLLMProviderPicker, openMentorVoicePicker, openNewInstanceDialog, openNewSkillDialog, openScheduleTaskDialog, openScreenSharePromptEditor, openSkillActionsMenu, parseReportUrlParams, previewCallConfigVoiceInline, previewMentorVoiceInline, previewVoice, pushConfiguration, reliableClick, reliableFill, resetCallConfig, retry, runConnectedInstanceChecks, runInstanceChecks, safeWaitForURL, saveCallConfig, saveScreenSharePrompts, saveVoiceSettings, scheduleTask, searchInstances, searchTasks, searchVoices, selectCallMode, selectDateFromCalendar, selectLLMModel, selectLlmProvider, selectPrivacyAction, selectSttProvider, selectTaskInList, selectTtsProvider, selectVoice, selectVoiceProvider, setBlockMessage, setCallLanguage, setEnableVideo, setEntitySelected, setOutputFilterEnabled, setPrivacyRouterEnabled, setScreenSharePrompt, setUseFunctionCallingEnabled, setupSandboxInstance, shouldAddNewRowWhenClickingAddRowButton, shouldAllowEditingCellValuesInCSVEditor, shouldCancelCombiningReports, shouldCloseCSVEditorWhenClickingCloseButton, shouldCloseCSVEditorWithoutSavingWhenClickingCancel, shouldCombineRecommendationReports, shouldDirectlyDownloadChatHistoryReportWithoutCSVEditor, shouldDisableOtherDownloadButtonsWhileGeneratingReport, shouldDisplayCSVInEditableTableFormat, shouldDisplayReportCards, shouldHaveCombinedReportDataTestIds, shouldOpenCSVEditorDialog, shouldOpenCSVEditorForUserMetadataReport, shouldSaveEditedCSVAndTriggerDownload, shouldShowCombiningReportsDialog, shouldVerifyCSVEditorDialogAccessibility, signUpWithEmailAndPassword, switchToMemoryTab, switchToPrivacyTab, switchToSandboxTab, switchToScreenShareTab, switchToSkillsTab, switchToTasksTab, switchToVoiceSubTab, switchToVoiceTab, teardownSandboxInstance, test, toggleAutoPush, toggleMemorySwitch, toggleSkill, verifyAgentConfigPromptsVisible, verifyAuditLogEmptyState, verifyAuditLogEntryStructure, verifyAuditLogGenericError, verifyAuditLogLoading, verifyAuditLogPermissionError, verifyAuditLogTableVisible, verifyConnectDisabledForUnhealthy, verifyConnectedInstanceCard, verifyCurrentPage, verifyDonePhase, verifyDownloadingPhase, verifyErrorPhase, verifyInstanceTableEmpty, verifyInstanceTableVisible, verifyMemoryExists, verifyMemoryNotExists, verifyMemoryTabMemoriesList, verifyMemoryTabSettings, verifyPreparingPhase, verifySkillVisible, verifySkillsEmptyState, verifySkillsTabVisible, waitForAuditLogDataLoaded, waitForBillingTabReady, waitForCreditBalanceLoaded, waitForDialogReady, waitForElementStable, waitForPageLoad, waitForPageReady, waitForReportDownload };
export type { AgentPromptField, AuthFlowType, AuthSetupConfig, BillingAutoRechargeStatus, CallMode, CreatePlaywrightConfigOptions, CreditBalancePlan, EnvConfig, LlmProvider, PlatformConfig, PrivacyAction, PrivacyEntity, ReportDownloadOptions, SafeWaitForURLOptions, ScreenSharePromptField, SignUpCredentials, SkillFormValues, StepFn, SttProvider, TaskRepeat, TaskStatus, TtsProvider, VoiceProvider };
