@stablyai/playwright-test 2.1.8 → 2.1.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/index.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var Ke = require('path');
3
+ var Kt = require('path');
4
4
  var require$$7 = require('url');
5
5
  var test$1 = require('@playwright/test');
6
6
  var playwrightBase = require('@stablyai/playwright-base');
7
7
  var index$1 = require('./index-CEcJkg8Q.cjs');
8
- var index = require('./index-CFruORhJ.cjs');
8
+ var index = require('./index-Li4YhdtX.cjs');
9
9
  require('node:buffer');
10
10
  require('node:path');
11
11
  require('node:child_process');
@@ -32,7 +32,7 @@ require('zlib');
32
32
  require('buffer');
33
33
 
34
34
  const getApiUrl = () => process.env.STABLY_API_URL ?? "https://api.stably.ai";
35
- const sdkVersion = "2.1.8" ;
35
+ const sdkVersion = "2.1.10" ;
36
36
  const assertNonEmptyString = (value, fieldName) => {
37
37
  if (!value.trim()) {
38
38
  throw new Error(`Missing required field: ${fieldName}`);
@@ -154,7 +154,7 @@ async function authWithGoogle(options) {
154
154
  }
155
155
 
156
156
  function getDirname(importMetaUrl) {
157
- return Ke.dirname(require$$7.fileURLToPath(importMetaUrl));
157
+ return Kt.dirname(require$$7.fileURLToPath(importMetaUrl));
158
158
  }
159
159
  function getFilename(importMetaUrl) {
160
160
  return require$$7.fileURLToPath(importMetaUrl);
@@ -189,7 +189,7 @@ Object.defineProperty(exports, "setApiKey", {
189
189
  enumerable: true,
190
190
  get: function () { return playwrightBase.setApiKey; }
191
191
  });
192
- exports.stablyReporter = index.Pa;
192
+ exports.stablyReporter = index.Ua;
193
193
  exports.authWithGoogle = authWithGoogle;
194
194
  exports.defineConfig = defineConfig;
195
195
  exports.expect = expect;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/auth-with-google.ts","../src/index.ts"],"sourcesContent":["import type { BrowserContext } from \"@playwright/test\";\n\nimport {\n createClient,\n postInternalV1TestAccountGoogleAuthState,\n} from \"@stablyai-internal/api-client\";\nimport { requireApiKey } from \"@stablyai/playwright-base\";\n\ndeclare const __PACKAGE_VERSION__: string;\n\ntype PlaywrightCookie = Parameters<BrowserContext[\"addCookies\"]>[0][number];\n\ntype LocalStorageEntry = {\n name: string;\n value: string;\n};\n\ntype StorageOrigin = {\n localStorage: LocalStorageEntry[];\n origin: string;\n};\n\n/**\n * Playwright-compatible storage state.\n */\nexport type GoogleStorageState = {\n cookies: PlaywrightCookie[];\n origins: StorageOrigin[];\n};\n\n/**\n * Input for {@link authWithGoogle}.\n */\nexport type AuthWithGoogleOptions = {\n /**\n * Browser context where auth state should be applied.\n */\n context: BrowserContext;\n /**\n * Google account email.\n */\n email: string;\n /**\n * Google account password.\n */\n password: string;\n /**\n * TOTP seed/secret used to generate the Google 2FA code.\n */\n otpSecret: string;\n /**\n * Force a cache refresh server-side. Defaults to `false`.\n */\n forceRefresh?: boolean;\n /**\n * Optional API key override. Defaults to the configured Stably API key.\n */\n apiKey?: string;\n};\n\nconst getApiUrl = (): string =>\n process.env.STABLY_API_URL ?? \"https://api.stably.ai\";\n\nconst sdkVersion =\n typeof __PACKAGE_VERSION__ !== \"undefined\"\n ? __PACKAGE_VERSION__\n : (process.env.npm_package_version ?? \"local\");\n\nconst assertNonEmptyString = (value: string, fieldName: string): void => {\n if (!value.trim()) {\n throw new Error(`Missing required field: ${fieldName}`);\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst parseCookie = (value: unknown): PlaywrightCookie => {\n if (!isRecord(value)) {\n throw new Error(\"Invalid Google storage state: cookie must be an object\");\n }\n\n const { domain } = value;\n const { name } = value;\n const { path } = value;\n const { sameSite } = value;\n const valueText = value.value;\n\n if (\n typeof domain !== \"string\" ||\n typeof name !== \"string\" ||\n typeof path !== \"string\" ||\n typeof valueText !== \"string\"\n ) {\n throw new Error(\n \"Invalid Google storage state: cookie is missing required fields\",\n );\n }\n\n return {\n ...(typeof value.expires === \"number\" ? { expires: value.expires } : {}),\n ...(typeof value.httpOnly === \"boolean\"\n ? { httpOnly: value.httpOnly }\n : {}),\n ...(typeof value.partitionKey === \"string\"\n ? { partitionKey: value.partitionKey }\n : {}),\n ...(typeof value.secure === \"boolean\" ? { secure: value.secure } : {}),\n ...(sameSite === \"Lax\" || sameSite === \"None\" || sameSite === \"Strict\"\n ? { sameSite }\n : {}),\n domain,\n name,\n path,\n value: valueText,\n };\n};\n\nconst parseLocalStorageEntry = (value: unknown): LocalStorageEntry => {\n if (!isRecord(value)) {\n throw new Error(\n \"Invalid Google storage state: localStorage entry must be an object\",\n );\n }\n\n const { name } = value;\n const storedValue = value.value;\n\n if (typeof name !== \"string\" || typeof storedValue !== \"string\") {\n throw new Error(\n \"Invalid Google storage state: localStorage entry must contain string name and value\",\n );\n }\n\n return { name, value: storedValue };\n};\n\nconst parseOrigin = (value: unknown): StorageOrigin => {\n if (!isRecord(value)) {\n throw new Error(\"Invalid Google storage state: origin must be an object\");\n }\n\n const { origin } = value;\n const rawLocalStorage = value.localStorage;\n\n if (typeof origin !== \"string\") {\n throw new Error(\"Invalid Google storage state: origin must be a string\");\n }\n\n if (!Array.isArray(rawLocalStorage)) {\n return { localStorage: [], origin };\n }\n\n return {\n localStorage: rawLocalStorage.map(parseLocalStorageEntry),\n origin,\n };\n};\n\nconst parseStorageState = (value: {\n cookies?: unknown[];\n origins?: unknown[];\n}): GoogleStorageState => ({\n cookies: Array.isArray(value.cookies) ? value.cookies.map(parseCookie) : [],\n origins: Array.isArray(value.origins) ? value.origins.map(parseOrigin) : [],\n});\n\nconst applyStorageStateToContext = async (\n context: BrowserContext,\n storageState: GoogleStorageState,\n): Promise<void> => {\n if (storageState.cookies.length > 0) {\n await context.addCookies(storageState.cookies);\n }\n\n for (const originState of storageState.origins) {\n if (originState.localStorage.length === 0) {\n continue;\n }\n\n const page = await context.newPage();\n try {\n await page.goto(originState.origin, { waitUntil: \"domcontentloaded\" });\n await page.evaluate((entries: LocalStorageEntry[]) => {\n for (const entry of entries) {\n window.localStorage.setItem(entry.name, entry.value);\n }\n }, originState.localStorage);\n } finally {\n await page.close();\n }\n }\n};\n\n/**\n * Signs in a Google test account and applies the authenticated session to a Playwright context.\n *\n * Use this when your test needs to start in an already-authenticated state without\n * manually driving the login UI. After this resolves, cookies and localStorage are\n * applied to the provided context and subsequent pages in that context can continue\n * as an authenticated user.\n *\n * @param options - Google credentials and target Playwright context.\n * @param options.context - Browser context to receive the authenticated session.\n * @param options.email - Google account email.\n * @param options.password - Google account password.\n * @param options.otpSecret - TOTP secret for 2FA. See https://docs.stably.ai/stably2/auth/google-otp-secret-helper.\n * @param options.forceRefresh - Optional flag to force regeneration of session state.\n * @param options.apiKey - Optional Stably API key override.\n *\n * @returns Resolves when auth state has been successfully applied to the context.\n *\n * @example\n * ```ts\n * import { test } from \"@stablyai/playwright-test\";\n *\n * test(\"opens Google settings as authenticated user\", async ({ context, page }) => {\n * await context.authWithGoogle({\n * email: \"qa@example.com\",\n * password: process.env.GOOGLE_TEST_PASSWORD!,\n * otpSecret: process.env.GOOGLE_TEST_OTP_SECRET!,\n * });\n *\n * await page.goto(\"https://myaccount.google.com\");\n * });\n * ```\n */\nexport async function authWithGoogle(\n options: AuthWithGoogleOptions,\n): Promise<void> {\n const apiKey = options.apiKey ?? requireApiKey();\n\n assertNonEmptyString(options.email, \"email\");\n assertNonEmptyString(options.password, \"password\");\n assertNonEmptyString(options.otpSecret, \"otpSecret\");\n\n const client = createClient({\n baseUrl: getApiUrl(),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"X-Client-Name\": \"stably-playwright-test\",\n \"X-Client-Version\": sdkVersion,\n \"X-Stably-SDK-Version\": sdkVersion,\n },\n });\n\n const response = await postInternalV1TestAccountGoogleAuthState({\n body: {\n email: options.email,\n forceRefresh: options.forceRefresh,\n otpSecret: options.otpSecret,\n password: options.password,\n },\n client,\n });\n\n if (response.error) {\n const errorMessage =\n \"error\" in response.error ? response.error.error : \"Unknown error\";\n throw new Error(`Failed to authenticate with Google: ${errorMessage}`);\n }\n\n const storageState = parseStorageState(response.data.storageState);\n await applyStorageStateToContext(options.context, storageState);\n}\n","import { dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport type { BrowserContext } from \"@playwright/test\";\nimport {\n defineConfig as playwrightDefineConfig,\n expect as playwrightExpect,\n test as playwrightTest,\n} from \"@playwright/test\";\nimport \"@stablyai/playwright-base\";\n\nimport type { Agent } from \"@stablyai/playwright-base\";\nimport {\n augmentBrowser,\n augmentBrowserContext,\n augmentPage,\n stablyPlaywrightMatchers,\n} from \"@stablyai/playwright-base\";\n\nimport type { StablyNotificationConfig } from \"@stablyai/playwright-reporter\";\nimport {\n authWithGoogle,\n type AuthWithGoogleOptions,\n type GoogleStorageState,\n} from \"./auth-with-google\";\n\nexport { stablyReporter } from \"@stablyai/playwright-reporter\";\nexport type {\n StablyReporterOptions,\n ProjectNotificationConfig,\n NotificationResultPolicy,\n StablyEmailNotificationConfig,\n StablySlackNotificationConfig,\n StablyNotificationConfig,\n} from \"@stablyai/playwright-reporter\";\nexport { Agent, setApiKey } from \"@stablyai/playwright-base\";\nexport { authWithGoogle, type AuthWithGoogleOptions, type GoogleStorageState };\nexport type {\n AIModel,\n GetLocatorsByAIOptions,\n GetLocatorsByAIResult,\n ScreenshotPromptOptions,\n} from \"@stablyai/playwright-base\";\n\n/**\n * Get the directory name from an import.meta.url.\n * This is the ESM equivalent of __dirname.\n *\n * @example\n * ```ts\n * import { getDirname } from '@stablyai/playwright-test';\n * const __dirname = getDirname(import.meta.url);\n *\n * // Use in tests for file paths\n * await page.setInputFiles('input', path.join(__dirname, 'fixtures', 'file.pdf'));\n * ```\n */\nexport function getDirname(importMetaUrl: string): string {\n return dirname(fileURLToPath(importMetaUrl));\n}\n\n/**\n * Get the filename from an import.meta.url.\n * This is the ESM equivalent of __filename.\n *\n * @example\n * ```ts\n * import { getFilename } from '@stablyai/playwright-test';\n * const __filename = getFilename(import.meta.url);\n * ```\n */\nexport function getFilename(importMetaUrl: string): string {\n return fileURLToPath(importMetaUrl);\n}\n\nexport const test: typeof playwrightTest = playwrightTest.extend<{\n agent: Agent;\n}>({\n agent: async (\n { context }: { context: BrowserContext },\n use: (agent: Agent) => Promise<void>,\n ) => {\n // Create a default agent from the default context\n const agent = context.newAgent();\n await use(agent);\n },\n browser: async ({ browser }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await use(augmentBrowser(browser as any) as any);\n },\n context: async ({ context }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion -- context augmentation requires type widening\n const augmentedContext = augmentBrowserContext(context as any) as any;\n if (!(\"authWithGoogle\" in augmentedContext)) {\n augmentedContext.authWithGoogle = (\n options: Omit<AuthWithGoogleOptions, \"context\">,\n ) => authWithGoogle({ context: augmentedContext, ...options });\n }\n\n await use(augmentedContext);\n },\n page: async ({ page }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await use(augmentPage(page as any) as any);\n },\n});\n\nexport const expect = playwrightExpect.extend(stablyPlaywrightMatchers);\n\nexport * from \"@playwright/test\";\n\nexport type StablyProjectConfig = {\n notifications?: StablyNotificationConfig;\n};\n\n/**\n * Stably-enhanced defineConfig with typed support for stably notification configuration in projects.\n * The `stably` property on projects is available via module augmentation of `@playwright/test`.\n *\n * @example\n * ```ts\n * import { defineConfig, stablyReporter } from \"@stablyai/playwright-test\";\n *\n * export default defineConfig({\n * reporter: [stablyReporter({ apiKey: \"...\" })],\n * projects: [\n * {\n * name: \"smoke\",\n * stably: {\n * notifications: {\n * slack: { channelName: \"#alerts\", notifyOnResult: \"failures-only\" },\n * },\n * },\n * },\n * ],\n * });\n * ```\n */\nexport const defineConfig = playwrightDefineConfig;\n\ndeclare module \"@playwright/test\" {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface LocatorAssertions {\n /**\n * Asserts that the locator satisfies a natural language condition using AI vision.\n *\n * Takes a screenshot of the locator and uses AI to verify whether the specified condition is met.\n *\n * @param condition - A natural language description of what should be true about the locator\n * @param options - Optional screenshot options (e.g., timeout)\n *\n * @example\n * ```typescript\n * await expect(page.locator('.button')).aiAssert('The button is disabled and grayed out');\n * ```\n */\n aiAssert(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n\n /**\n * @deprecated Use `aiAssert` instead. This method will be removed in a future version.\n */\n toMatchScreenshotPrompt(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface PageAssertions {\n /**\n * Asserts that the page satisfies a natural language condition using AI vision.\n *\n * Takes a screenshot of the page and uses AI to verify whether the specified condition is met.\n *\n * @param condition - A natural language description of what should be true about the page\n * @param options - Optional screenshot options (e.g., fullPage, timeout)\n *\n * @example\n * ```typescript\n * await expect(page).aiAssert('The page shows a success message after form submission');\n * ```\n */\n aiAssert(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n\n /**\n * @deprecated Use `aiAssert` instead. This method will be removed in a future version.\n */\n toMatchScreenshotPrompt(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n }\n\n // Add agent fixture to test args\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface PlaywrightTestArgs {\n agent: Agent;\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface BrowserContext {\n /**\n * Generates and applies Google auth state to this context.\n *\n * Calls Stably's Google auth-state endpoint and proactively sets cookies and\n * localStorage values on this context.\n */\n authWithGoogle(\n options: Omit<AuthWithGoogleOptions, \"context\">,\n ): Promise<void>;\n }\n\n // Add stably config to project configuration\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface Project {\n stably?: StablyProjectConfig;\n }\n}\n"],"names":["requireApiKey","createClient","postInternalV1TestAccountGoogleAuthState","dirname","fileURLToPath","playwrightTest","augmentBrowser","augmentBrowserContext","augmentPage","playwrightExpect","stablyPlaywrightMatchers","playwrightDefineConfig"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/auth-with-google.ts","../src/index.ts"],"sourcesContent":["import type { BrowserContext } from \"@playwright/test\";\n\nimport {\n createClient,\n postInternalV1TestAccountGoogleAuthState,\n} from \"@stablyai-internal/api-client\";\nimport { requireApiKey } from \"@stablyai/playwright-base\";\n\ndeclare const __PACKAGE_VERSION__: string;\n\ntype PlaywrightCookie = Parameters<BrowserContext[\"addCookies\"]>[0][number];\n\ntype LocalStorageEntry = {\n name: string;\n value: string;\n};\n\ntype StorageOrigin = {\n localStorage: LocalStorageEntry[];\n origin: string;\n};\n\n/**\n * Playwright-compatible storage state.\n */\nexport type GoogleStorageState = {\n cookies: PlaywrightCookie[];\n origins: StorageOrigin[];\n};\n\n/**\n * Input for {@link authWithGoogle}.\n */\nexport type AuthWithGoogleOptions = {\n /**\n * Browser context where auth state should be applied.\n */\n context: BrowserContext;\n /**\n * Google account email.\n */\n email: string;\n /**\n * Google account password.\n */\n password: string;\n /**\n * TOTP seed/secret used to generate the Google 2FA code.\n */\n otpSecret: string;\n /**\n * Force a cache refresh server-side. Defaults to `false`.\n */\n forceRefresh?: boolean;\n /**\n * Optional API key override. Defaults to the configured Stably API key.\n */\n apiKey?: string;\n};\n\nconst getApiUrl = (): string =>\n process.env.STABLY_API_URL ?? \"https://api.stably.ai\";\n\nconst sdkVersion =\n typeof __PACKAGE_VERSION__ !== \"undefined\"\n ? __PACKAGE_VERSION__\n : (process.env.npm_package_version ?? \"local\");\n\nconst assertNonEmptyString = (value: string, fieldName: string): void => {\n if (!value.trim()) {\n throw new Error(`Missing required field: ${fieldName}`);\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst parseCookie = (value: unknown): PlaywrightCookie => {\n if (!isRecord(value)) {\n throw new Error(\"Invalid Google storage state: cookie must be an object\");\n }\n\n const { domain } = value;\n const { name } = value;\n const { path } = value;\n const { sameSite } = value;\n const valueText = value.value;\n\n if (\n typeof domain !== \"string\" ||\n typeof name !== \"string\" ||\n typeof path !== \"string\" ||\n typeof valueText !== \"string\"\n ) {\n throw new Error(\n \"Invalid Google storage state: cookie is missing required fields\",\n );\n }\n\n return {\n ...(typeof value.expires === \"number\" ? { expires: value.expires } : {}),\n ...(typeof value.httpOnly === \"boolean\"\n ? { httpOnly: value.httpOnly }\n : {}),\n ...(typeof value.partitionKey === \"string\"\n ? { partitionKey: value.partitionKey }\n : {}),\n ...(typeof value.secure === \"boolean\" ? { secure: value.secure } : {}),\n ...(sameSite === \"Lax\" || sameSite === \"None\" || sameSite === \"Strict\"\n ? { sameSite }\n : {}),\n domain,\n name,\n path,\n value: valueText,\n };\n};\n\nconst parseLocalStorageEntry = (value: unknown): LocalStorageEntry => {\n if (!isRecord(value)) {\n throw new Error(\n \"Invalid Google storage state: localStorage entry must be an object\",\n );\n }\n\n const { name } = value;\n const storedValue = value.value;\n\n if (typeof name !== \"string\" || typeof storedValue !== \"string\") {\n throw new Error(\n \"Invalid Google storage state: localStorage entry must contain string name and value\",\n );\n }\n\n return { name, value: storedValue };\n};\n\nconst parseOrigin = (value: unknown): StorageOrigin => {\n if (!isRecord(value)) {\n throw new Error(\"Invalid Google storage state: origin must be an object\");\n }\n\n const { origin } = value;\n const rawLocalStorage = value.localStorage;\n\n if (typeof origin !== \"string\") {\n throw new Error(\"Invalid Google storage state: origin must be a string\");\n }\n\n if (!Array.isArray(rawLocalStorage)) {\n return { localStorage: [], origin };\n }\n\n return {\n localStorage: rawLocalStorage.map(parseLocalStorageEntry),\n origin,\n };\n};\n\nconst parseStorageState = (value: {\n cookies?: unknown[];\n origins?: unknown[];\n}): GoogleStorageState => ({\n cookies: Array.isArray(value.cookies) ? value.cookies.map(parseCookie) : [],\n origins: Array.isArray(value.origins) ? value.origins.map(parseOrigin) : [],\n});\n\nconst applyStorageStateToContext = async (\n context: BrowserContext,\n storageState: GoogleStorageState,\n): Promise<void> => {\n if (storageState.cookies.length > 0) {\n await context.addCookies(storageState.cookies);\n }\n\n for (const originState of storageState.origins) {\n if (originState.localStorage.length === 0) {\n continue;\n }\n\n const page = await context.newPage();\n try {\n await page.goto(originState.origin, { waitUntil: \"domcontentloaded\" });\n await page.evaluate((entries: LocalStorageEntry[]) => {\n for (const entry of entries) {\n window.localStorage.setItem(entry.name, entry.value);\n }\n }, originState.localStorage);\n } finally {\n await page.close();\n }\n }\n};\n\n/**\n * Signs in a Google test account and applies the authenticated session to a Playwright context.\n *\n * Use this when your test needs to start in an already-authenticated state without\n * manually driving the login UI. After this resolves, cookies and localStorage are\n * applied to the provided context and subsequent pages in that context can continue\n * as an authenticated user.\n *\n * @param options - Google credentials and target Playwright context.\n * @param options.context - Browser context to receive the authenticated session.\n * @param options.email - Google account email.\n * @param options.password - Google account password.\n * @param options.otpSecret - TOTP secret for 2FA. See https://docs.stably.ai/stably2/auth/google-otp-secret-helper.\n * @param options.forceRefresh - Optional flag to force regeneration of session state.\n * @param options.apiKey - Optional Stably API key override.\n *\n * @returns Resolves when auth state has been successfully applied to the context.\n *\n * @example\n * ```ts\n * import { test } from \"@stablyai/playwright-test\";\n *\n * test(\"opens Google settings as authenticated user\", async ({ context, page }) => {\n * await context.authWithGoogle({\n * email: \"qa@example.com\",\n * password: process.env.GOOGLE_TEST_PASSWORD!,\n * otpSecret: process.env.GOOGLE_TEST_OTP_SECRET!,\n * });\n *\n * await page.goto(\"https://myaccount.google.com\");\n * });\n * ```\n */\nexport async function authWithGoogle(\n options: AuthWithGoogleOptions,\n): Promise<void> {\n const apiKey = options.apiKey ?? requireApiKey();\n\n assertNonEmptyString(options.email, \"email\");\n assertNonEmptyString(options.password, \"password\");\n assertNonEmptyString(options.otpSecret, \"otpSecret\");\n\n const client = createClient({\n baseUrl: getApiUrl(),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"X-Client-Name\": \"stably-playwright-test\",\n \"X-Client-Version\": sdkVersion,\n \"X-Stably-SDK-Version\": sdkVersion,\n },\n });\n\n const response = await postInternalV1TestAccountGoogleAuthState({\n body: {\n email: options.email,\n forceRefresh: options.forceRefresh,\n otpSecret: options.otpSecret,\n password: options.password,\n },\n client,\n });\n\n if (response.error) {\n const errorMessage =\n \"error\" in response.error ? response.error.error : \"Unknown error\";\n throw new Error(`Failed to authenticate with Google: ${errorMessage}`);\n }\n\n const storageState = parseStorageState(response.data.storageState);\n await applyStorageStateToContext(options.context, storageState);\n}\n","import { dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport type { BrowserContext } from \"@playwright/test\";\nimport {\n defineConfig as playwrightDefineConfig,\n expect as playwrightExpect,\n test as playwrightTest,\n} from \"@playwright/test\";\nimport \"@stablyai/playwright-base\";\n\nimport type { Agent } from \"@stablyai/playwright-base\";\nimport {\n augmentBrowser,\n augmentBrowserContext,\n augmentPage,\n stablyPlaywrightMatchers,\n} from \"@stablyai/playwright-base\";\n\nimport type { StablyNotificationConfig } from \"@stablyai/playwright-reporter\";\nimport {\n authWithGoogle,\n type AuthWithGoogleOptions,\n type GoogleStorageState,\n} from \"./auth-with-google\";\n\nexport { stablyReporter } from \"@stablyai/playwright-reporter\";\nexport type {\n StablyReporterOptions,\n ProjectNotificationConfig,\n NotificationResultPolicy,\n StablyEmailNotificationConfig,\n StablySlackNotificationConfig,\n StablyNotificationConfig,\n} from \"@stablyai/playwright-reporter\";\nexport { Agent, setApiKey } from \"@stablyai/playwright-base\";\nexport { authWithGoogle, type AuthWithGoogleOptions, type GoogleStorageState };\nexport type {\n AIModel,\n GetLocatorsByAIOptions,\n GetLocatorsByAIResult,\n ScreenshotPromptOptions,\n} from \"@stablyai/playwright-base\";\n\n/**\n * Get the directory name from an import.meta.url.\n * This is the ESM equivalent of __dirname.\n *\n * @example\n * ```ts\n * import { getDirname } from '@stablyai/playwright-test';\n * const __dirname = getDirname(import.meta.url);\n *\n * // Use in tests for file paths\n * await page.setInputFiles('input', path.join(__dirname, 'fixtures', 'file.pdf'));\n * ```\n */\nexport function getDirname(importMetaUrl: string): string {\n return dirname(fileURLToPath(importMetaUrl));\n}\n\n/**\n * Get the filename from an import.meta.url.\n * This is the ESM equivalent of __filename.\n *\n * @example\n * ```ts\n * import { getFilename } from '@stablyai/playwright-test';\n * const __filename = getFilename(import.meta.url);\n * ```\n */\nexport function getFilename(importMetaUrl: string): string {\n return fileURLToPath(importMetaUrl);\n}\n\nexport const test: typeof playwrightTest = playwrightTest.extend<{\n agent: Agent;\n}>({\n agent: async (\n { context }: { context: BrowserContext },\n use: (agent: Agent) => Promise<void>,\n ) => {\n // Create a default agent from the default context\n const agent = context.newAgent();\n await use(agent);\n },\n browser: async ({ browser }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await use(augmentBrowser(browser as any) as any);\n },\n context: async ({ context }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion -- context augmentation requires type widening\n const augmentedContext = augmentBrowserContext(context as any) as any;\n if (!(\"authWithGoogle\" in augmentedContext)) {\n augmentedContext.authWithGoogle = (\n options: Omit<AuthWithGoogleOptions, \"context\">,\n ) => authWithGoogle({ context: augmentedContext, ...options });\n }\n\n await use(augmentedContext);\n },\n page: async ({ page }, use) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await use(augmentPage(page as any) as any);\n },\n});\n\nexport const expect = playwrightExpect.extend(stablyPlaywrightMatchers);\n\nexport * from \"@playwright/test\";\n\nexport type StablyProjectConfig = {\n notifications?: StablyNotificationConfig;\n};\n\n/**\n * Stably-enhanced defineConfig with typed support for stably notification configuration in projects.\n * The `stably` property on projects is available via module augmentation of `@playwright/test`.\n *\n * @example\n * ```ts\n * import { defineConfig, stablyReporter } from \"@stablyai/playwright-test\";\n *\n * export default defineConfig({\n * reporter: [stablyReporter({ apiKey: \"...\" })],\n * projects: [\n * {\n * name: \"smoke\",\n * stably: {\n * notifications: {\n * slack: { channelName: \"#alerts\", notifyOnResult: \"failures-only\" },\n * },\n * },\n * },\n * ],\n * });\n * ```\n */\nexport const defineConfig = playwrightDefineConfig;\n\ndeclare module \"@playwright/test\" {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface LocatorAssertions {\n /**\n * Asserts that the locator satisfies a natural language condition using AI vision.\n *\n * Takes a screenshot of the locator and uses AI to verify whether the specified condition is met.\n *\n * @param condition - A natural language description of what should be true about the locator\n * @param options - Optional screenshot options (e.g., timeout)\n *\n * @example\n * ```typescript\n * await expect(page.locator('.button')).aiAssert('The button is disabled and grayed out');\n * ```\n */\n aiAssert(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n\n /**\n * @deprecated Use `aiAssert` instead. This method will be removed in a future version.\n */\n toMatchScreenshotPrompt(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface PageAssertions {\n /**\n * Asserts that the page satisfies a natural language condition using AI vision.\n *\n * Takes a screenshot of the page and uses AI to verify whether the specified condition is met.\n *\n * @param condition - A natural language description of what should be true about the page\n * @param options - Optional screenshot options (e.g., fullPage, timeout)\n *\n * @example\n * ```typescript\n * await expect(page).aiAssert('The page shows a success message after form submission');\n * ```\n */\n aiAssert(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n\n /**\n * @deprecated Use `aiAssert` instead. This method will be removed in a future version.\n */\n toMatchScreenshotPrompt(\n condition: string,\n // eslint-disable-next-line @typescript-eslint/consistent-type-imports\n options?: import(\"@stablyai/playwright-base\").ScreenshotPromptOptions,\n ): Promise<void>;\n }\n\n // Add agent fixture to test args\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface PlaywrightTestArgs {\n agent: Agent;\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface BrowserContext {\n /**\n * Generates and applies Google auth state to this context.\n *\n * Calls Stably's Google auth-state endpoint and proactively sets cookies and\n * localStorage values on this context.\n */\n authWithGoogle(\n options: Omit<AuthWithGoogleOptions, \"context\">,\n ): Promise<void>;\n }\n\n // Add stably config to project configuration\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface Project {\n stably?: StablyProjectConfig;\n }\n}\n"],"names":["requireApiKey","createClient","postInternalV1TestAccountGoogleAuthState","dirname","fileURLToPath","playwrightTest","augmentBrowser","augmentBrowserContext","augmentPage","playwrightExpect","stablyPlaywrightMatchers","playwrightDefineConfig"],"mappings":"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"}
@@ -45532,6 +45532,8 @@ type ProjectNotificationConfig = {
45532
45532
  type StablyReporterOptions = {
45533
45533
  apiKey?: string;
45534
45534
  projectId?: string;
45535
+ source?: string;
45536
+ cliVersion?: string;
45535
45537
  notificationConfigs?: ProjectNotificationConfig[];
45536
45538
  sensitiveValues?: readonly string[];
45537
45539
  };
@@ -45539,6 +45541,8 @@ declare class StablyReporter implements Reporter {
45539
45541
  private readonly wsClient;
45540
45542
  private readonly apiKey;
45541
45543
  private readonly projectId;
45544
+ private readonly source?;
45545
+ private readonly cliVersion?;
45542
45546
  private readonly pendingOperations;
45543
45547
  private readonly pendingUploads;
45544
45548
  private testSuiteRunId;
@@ -45558,8 +45562,9 @@ declare class StablyReporter implements Reporter {
45558
45562
  private suite?;
45559
45563
  private pendingQueuedSpecs?;
45560
45564
  private readonly attachmentFiles;
45561
- private readonly pendingUploadUrlRequests;
45565
+ private readonly uploadUrlWaitQueue;
45562
45566
  constructor(options?: StablyReporterOptions);
45567
+ private handleUploadUrlsMessage;
45563
45568
  onBegin(config: FullConfig, suite: Suite): void;
45564
45569
  getSuiteRunId(config: FullConfig<{}, {}>): string;
45565
45570
  onTestBegin(test: TestCase, result: TestResult): void;
@@ -45586,4 +45591,4 @@ declare function stablyReporter(options?: StablyReporterOptions): [string, any];
45586
45591
 
45587
45592
  export { StablyReporter as d, stablyReporter as s };
45588
45593
  export type { NotificationResultPolicy as N, ProjectNotificationConfig as P, StablyNotificationConfig as S, StablyEmailNotificationConfig as a, StablyReporterOptions as b, StablySlackNotificationConfig as c };
45589
- //# sourceMappingURL=index.d-Cdd7-KS-.d.cts.map
45594
+ //# sourceMappingURL=index.d-Cbdkyfd5.d.cts.map