browsecraft 0.1.0
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/LICENSE +21 -0
- package/dist/chunk-77HRTGXZ.js +2004 -0
- package/dist/chunk-77HRTGXZ.js.map +1 -0
- package/dist/chunk-KIPQFK3Y.cjs +2021 -0
- package/dist/chunk-KIPQFK3Y.cjs.map +1 -0
- package/dist/cli.cjs +297 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +295 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +831 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +984 -0
- package/dist/index.d.ts +984 -0
- package/dist/index.js +632 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/expect.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================================\n// Browsecraft - Assertion System\n// Auto-retrying assertions that just work. No flaky tests.\n//\n// expect(page).toHaveURL('/dashboard');\n// expect(page.get('Submit')).toBeVisible();\n// expect(page.get('Cart')).toHaveText('3 items');\n// ============================================================================\n\nimport type { Page, ElementHandle } from './page.js';\nimport { waitFor } from './wait.js';\n\n/** Default timeout for assertions (5s is plenty for UI checks) */\nconst DEFAULT_ASSERTION_TIMEOUT = 5_000;\n\n/** Options shared by all assertion matchers */\ninterface MatcherOptions {\n\t/** Timeout in ms (default: 5000) */\n\ttimeout?: number;\n}\n\n// ---------------------------------------------------------------------------\n// expect() entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Create assertions on Pages or ElementHandles.\n * All matchers auto-retry until they pass or timeout.\n *\n * ```ts\n * await expect(page).toHaveURL('/dashboard');\n * await expect(page).toHaveTitle('My App');\n * await expect(page.get('Welcome')).toBeVisible();\n * await expect(page.get('Submit')).toHaveText('Submit Order');\n * ```\n */\nexport function expect(subject: Page): PageAssertions;\nexport function expect(subject: ElementHandle): ElementAssertions;\nexport function expect(subject: Page | ElementHandle): PageAssertions | ElementAssertions {\n\tif (subject instanceof (\n\t\t// We can't import Page directly for instanceof due to circular deps,\n\t\t// so we check for the contextId property which only Page has\n\t\tObject\n\t) && 'contextId' in subject && 'session' in subject && !('target' in subject)) {\n\t\treturn new PageAssertions(subject as Page);\n\t}\n\treturn new ElementAssertions(subject as ElementHandle);\n}\n\n// ---------------------------------------------------------------------------\n// Page Assertions\n// ---------------------------------------------------------------------------\n\n/**\n * Assertions for a Page. All matchers auto-retry.\n */\nclass PageAssertions {\n\tprivate page: Page;\n\tprivate _not = false;\n\n\tconstructor(page: Page) {\n\t\tthis.page = page;\n\t}\n\n\t/** Negate the assertion */\n\tget not(): PageAssertions {\n\t\tconst negated = new PageAssertions(this.page);\n\t\tnegated._not = !this._not;\n\t\treturn negated;\n\t}\n\n\t/**\n\t * Assert the page URL contains or matches the expected value.\n\t *\n\t * ```ts\n\t * await expect(page).toHaveURL('/dashboard');\n\t * await expect(page).toHaveURL(/dashboard/);\n\t * ```\n\t */\n\tasync toHaveURL(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`URL to ${isNot ? 'not ' : ''}match ${expected}`,\n\t\t\tasync () => {\n\t\t\t\tconst actual = await this.page.url();\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? actual.includes(expected)\n\t\t\t\t\t: expected.test(actual);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected URL ${isNot ? 'not ' : ''}to match ${expected}`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the page title matches.\n\t *\n\t * ```ts\n\t * await expect(page).toHaveTitle('Dashboard');\n\t * await expect(page).toHaveTitle(/Dashboard/);\n\t * ```\n\t */\n\tasync toHaveTitle(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`title to ${isNot ? 'not ' : ''}match \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst actual = await this.page.title();\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? actual.includes(expected)\n\t\t\t\t\t: expected.test(actual);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected title ${isNot ? 'not ' : ''}to match \"${expected}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the page content (HTML body text) contains the expected text.\n\t *\n\t * ```ts\n\t * await expect(page).toHaveContent('Welcome back');\n\t * await expect(page).toHaveContent(/logged in as \\w+/);\n\t * ```\n\t */\n\tasync toHaveContent(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastContent = '';\n\n\t\tawait retry(\n\t\t\t`page to ${isNot ? 'not ' : ''}contain \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst content = await this.page.evaluate<string>('document.body?.innerText || \"\"');\n\t\t\t\tlastContent = content.slice(0, 200); // keep for error message\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? content.includes(expected)\n\t\t\t\t\t: expected.test(content);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected page ${isNot ? 'not ' : ''}to contain \"${expected}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Element Assertions\n// ---------------------------------------------------------------------------\n\n/**\n * Assertions for an ElementHandle. All matchers auto-retry.\n */\nclass ElementAssertions {\n\tprivate element: ElementHandle;\n\tprivate _not = false;\n\n\tconstructor(element: ElementHandle) {\n\t\tthis.element = element;\n\t}\n\n\t/** Negate the assertion */\n\tget not(): ElementAssertions {\n\t\tconst negated = new ElementAssertions(this.element);\n\t\tnegated._not = !this._not;\n\t\treturn negated;\n\t}\n\n\t/**\n\t * Assert the element is visible on the page.\n\t *\n\t * ```ts\n\t * await expect(page.get('Welcome')).toBeVisible();\n\t * await expect(page.get('Error')).not.toBeVisible();\n\t * ```\n\t */\n\tasync toBeVisible(options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}be visible`,\n\t\t\tasync () => {\n\t\t\t\tconst visible = await this.element.isVisible();\n\t\t\t\treturn isNot ? !visible : visible;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to be visible`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the element is hidden (not visible).\n\t *\n\t * ```ts\n\t * await expect(page.get('Loading')).toBeHidden();\n\t * ```\n\t */\n\tasync toBeHidden(options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}be hidden`,\n\t\t\tasync () => {\n\t\t\t\tconst visible = await this.element.isVisible();\n\t\t\t\tconst hidden = !visible;\n\t\t\t\treturn isNot ? !hidden : hidden;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to be hidden`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the element's text content matches exactly.\n\t *\n\t * ```ts\n\t * await expect(page.get('h1')).toHaveText('Welcome');\n\t * await expect(page.get('.count')).toHaveText(/\\d+ items/);\n\t * ```\n\t */\n\tasync toHaveText(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastActual = '';\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have text \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst actual = (await this.element.textContent()).trim();\n\t\t\t\tlastActual = actual;\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? actual === expected\n\t\t\t\t\t: expected.test(actual);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to have text \"${expected}\", but got \"${lastActual}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the element's text content contains the expected substring.\n\t *\n\t * ```ts\n\t * await expect(page.get('.message')).toContainText('success');\n\t * ```\n\t */\n\tasync toContainText(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastActual = '';\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}contain text \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst actual = (await this.element.textContent()).trim();\n\t\t\t\tlastActual = actual;\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? actual.includes(expected)\n\t\t\t\t\t: expected.test(actual);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to contain text \"${expected}\", but got \"${lastActual}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the number of matching elements.\n\t *\n\t * ```ts\n\t * await expect(page.get('li')).toHaveCount(5);\n\t * ```\n\t */\n\tasync toHaveCount(expected: number, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastCount = 0;\n\n\t\tawait retry(\n\t\t\t`element count to ${isNot ? 'not ' : ''}be ${expected}`,\n\t\t\tasync () => {\n\t\t\t\tconst count = await this.element.count();\n\t\t\t\tlastCount = count;\n\t\t\t\tconst matches = count === expected;\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected ${isNot ? 'not ' : ''}${expected} elements, but found ${lastCount}`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert the element has a specific attribute value.\n\t *\n\t * ```ts\n\t * await expect(page.get('input')).toHaveAttribute('type', 'email');\n\t * await expect(page.get('a')).toHaveAttribute('href', /login/);\n\t * ```\n\t */\n\tasync toHaveAttribute(name: string, expected?: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastValue: string | null = null;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have attribute \"${name}\"${expected !== undefined ? `=\"${expected}\"` : ''}`,\n\t\t\tasync () => {\n\t\t\t\tconst value = await this.element.getAttribute(name);\n\t\t\t\tlastValue = value;\n\n\t\t\t\tif (expected === undefined) {\n\t\t\t\t\t// Just checking the attribute exists\n\t\t\t\t\tconst has = value !== null;\n\t\t\t\t\treturn isNot ? !has : has;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn isNot; // no value -- pass if negated, fail otherwise\n\t\t\t\t}\n\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? value === expected\n\t\t\t\t\t: expected.test(value);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\tif (expected === undefined) {\n\t\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to have attribute \"${name}\"`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `Expected attribute \"${name}\" ${isNot ? 'not ' : ''}to be \"${expected}\", but got \"${lastValue}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an input/textarea/select has a specific value.\n\t *\n\t * ```ts\n\t * await expect(page.get('Email')).toHaveValue('user@test.com');\n\t * ```\n\t */\n\tasync toHaveValue(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastValue = '';\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have value \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\t// Get value using script evaluation\n\t\t\t\tconst located = await this.element.locate(timeout);\n\t\t\t\tconst ref = located.node.sharedId\n\t\t\t\t\t? { sharedId: located.node.sharedId, handle: located.node.handle }\n\t\t\t\t\t: null;\n\n\t\t\t\tif (!ref) return false;\n\n\t\t\t\tconst result = await this.element.page.session.script.callFunction({\n\t\t\t\t\tfunctionDeclaration: 'function(el) { return el.value ?? \"\"; }',\n\t\t\t\t\ttarget: { context: this.element.page.contextId },\n\t\t\t\t\targuments: [ref],\n\t\t\t\t\tawaitPromise: false,\n\t\t\t\t});\n\n\t\t\t\tconst value = result.type === 'success' && result.result?.type === 'string'\n\t\t\t\t\t? (result.result as { value: string }).value\n\t\t\t\t\t: '';\n\t\t\t\tlastValue = value;\n\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? value === expected\n\t\t\t\t\t: expected.test(value);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected value ${isNot ? 'not ' : ''}to be \"${expected}\", but got \"${lastValue}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert a checkbox/radio is checked.\n\t *\n\t * ```ts\n\t * await expect(page.get('Terms')).toBeChecked();\n\t * await expect(page.get('Newsletter')).not.toBeChecked();\n\t * ```\n\t */\n\tasync toBeChecked(options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}be checked`,\n\t\t\tasync () => {\n\t\t\t\tconst located = await this.element.locate(timeout);\n\t\t\t\tconst ref = located.node.sharedId\n\t\t\t\t\t? { sharedId: located.node.sharedId, handle: located.node.handle }\n\t\t\t\t\t: null;\n\n\t\t\t\tif (!ref) return false;\n\n\t\t\t\tconst result = await this.element.page.session.script.callFunction({\n\t\t\t\t\tfunctionDeclaration: 'function(el) { return !!el.checked; }',\n\t\t\t\t\ttarget: { context: this.element.page.contextId },\n\t\t\t\t\targuments: [ref],\n\t\t\t\t\tawaitPromise: false,\n\t\t\t\t});\n\n\t\t\t\tconst checked = result.type === 'success' &&\n\t\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t\t\treturn isNot ? !checked : checked;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to be checked`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element is enabled (not disabled).\n\t *\n\t * ```ts\n\t * await expect(page.get('Submit')).toBeEnabled();\n\t * ```\n\t */\n\tasync toBeEnabled(options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}be enabled`,\n\t\t\tasync () => {\n\t\t\t\tconst located = await this.element.locate(timeout);\n\t\t\t\tconst ref = located.node.sharedId\n\t\t\t\t\t? { sharedId: located.node.sharedId, handle: located.node.handle }\n\t\t\t\t\t: null;\n\n\t\t\t\tif (!ref) return false;\n\n\t\t\t\tconst result = await this.element.page.session.script.callFunction({\n\t\t\t\t\tfunctionDeclaration: 'function(el) { return !el.disabled; }',\n\t\t\t\t\ttarget: { context: this.element.page.contextId },\n\t\t\t\t\targuments: [ref],\n\t\t\t\t\tawaitPromise: false,\n\t\t\t\t});\n\n\t\t\t\tconst enabled = result.type === 'success' &&\n\t\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t\t\treturn isNot ? !enabled : enabled;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to be enabled`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element is disabled.\n\t *\n\t * ```ts\n\t * await expect(page.get('Submit')).toBeDisabled();\n\t * ```\n\t */\n\tasync toBeDisabled(options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}be disabled`,\n\t\t\tasync () => {\n\t\t\t\tconst located = await this.element.locate(timeout);\n\t\t\t\tconst ref = located.node.sharedId\n\t\t\t\t\t? { sharedId: located.node.sharedId, handle: located.node.handle }\n\t\t\t\t\t: null;\n\n\t\t\t\tif (!ref) return false;\n\n\t\t\t\tconst result = await this.element.page.session.script.callFunction({\n\t\t\t\t\tfunctionDeclaration: 'function(el) { return !!el.disabled; }',\n\t\t\t\t\ttarget: { context: this.element.page.contextId },\n\t\t\t\t\targuments: [ref],\n\t\t\t\t\tawaitPromise: false,\n\t\t\t\t});\n\n\t\t\t\tconst disabled = result.type === 'success' &&\n\t\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t\t\treturn isNot ? !disabled : disabled;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to be disabled`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element has a specific CSS class.\n\t *\n\t * ```ts\n\t * await expect(page.get('.alert')).toHaveClass('alert-success');\n\t * ```\n\t */\n\tasync toHaveClass(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastClasses = '';\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have class \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst classes = await this.element.getAttribute('class') ?? '';\n\t\t\t\tlastClasses = classes;\n\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? classes.split(/\\s+/).includes(expected)\n\t\t\t\t\t: expected.test(classes);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to have class \"${expected}\", but got \"${lastClasses}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element has a specific CSS property value.\n\t *\n\t * ```ts\n\t * await expect(page.get('.banner')).toHaveCSS('color', 'rgb(255, 0, 0)');\n\t * await expect(page.get('.box')).toHaveCSS('display', 'flex');\n\t * ```\n\t */\n\tasync toHaveCSS(property: string, expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastValue = '';\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have CSS \"${property}: ${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst located = await this.element.locate(timeout);\n\t\t\t\tconst ref = located.node.sharedId\n\t\t\t\t\t? { sharedId: located.node.sharedId, handle: located.node.handle }\n\t\t\t\t\t: null;\n\n\t\t\t\tif (!ref) return false;\n\n\t\t\t\tconst result = await this.element.page.session.script.callFunction({\n\t\t\t\t\tfunctionDeclaration: `function(el, prop) { return window.getComputedStyle(el).getPropertyValue(prop); }`,\n\t\t\t\t\ttarget: { context: this.element.page.contextId },\n\t\t\t\t\targuments: [ref, { type: 'string', value: property }],\n\t\t\t\t\tawaitPromise: false,\n\t\t\t\t});\n\n\t\t\t\tconst value = result.type === 'success' && result.result?.type === 'string'\n\t\t\t\t\t? (result.result as { value: string }).value\n\t\t\t\t\t: '';\n\t\t\t\tlastValue = value;\n\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? value === expected\n\t\t\t\t\t: expected.test(value);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected CSS \"${property}\" ${isNot ? 'not ' : ''}to be \"${expected}\", but got \"${lastValue}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element has a specific id attribute.\n\t *\n\t * ```ts\n\t * await expect(page.get('Submit')).toHaveId('submit-btn');\n\t * ```\n\t */\n\tasync toHaveId(expected: string, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastId: string | null = null;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have id \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst id = await this.element.getAttribute('id');\n\t\t\t\tlastId = id;\n\t\t\t\tconst matches = id === expected;\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to have id \"${expected}\", but got \"${lastId}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element has a specific placeholder text.\n\t *\n\t * ```ts\n\t * await expect(page.get({ selector: '#email' })).toHavePlaceholder('Enter your email');\n\t * ```\n\t */\n\tasync toHavePlaceholder(expected: string | RegExp, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastPlaceholder: string | null = null;\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have placeholder \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst placeholder = await this.element.getAttribute('placeholder');\n\t\t\t\tlastPlaceholder = placeholder;\n\n\t\t\t\tif (placeholder === null) return isNot;\n\n\t\t\t\tconst matches = typeof expected === 'string'\n\t\t\t\t\t? placeholder === expected\n\t\t\t\t\t: expected.test(placeholder);\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected placeholder ${isNot ? 'not ' : ''}to be \"${expected}\", but got \"${lastPlaceholder}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * Assert an element has a specific ARIA role.\n\t *\n\t * ```ts\n\t * await expect(page.get('Submit')).toHaveRole('button');\n\t * ```\n\t */\n\tasync toHaveRole(expected: string, options?: MatcherOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? DEFAULT_ASSERTION_TIMEOUT;\n\t\tconst isNot = this._not;\n\t\tlet lastRole = '';\n\n\t\tawait retry(\n\t\t\t`element to ${isNot ? 'not ' : ''}have role \"${expected}\"`,\n\t\t\tasync () => {\n\t\t\t\tconst located = await this.element.locate(timeout);\n\t\t\t\tconst ref = located.node.sharedId\n\t\t\t\t\t? { sharedId: located.node.sharedId, handle: located.node.handle }\n\t\t\t\t\t: null;\n\n\t\t\t\tif (!ref) return false;\n\n\t\t\t\t// Try explicit role attribute first, fall back to computed role\n\t\t\t\tconst result = await this.element.page.session.script.callFunction({\n\t\t\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\t\t\treturn el.getAttribute('role') || el.computedRole || '';\n\t\t\t\t\t}`,\n\t\t\t\t\ttarget: { context: this.element.page.contextId },\n\t\t\t\t\targuments: [ref],\n\t\t\t\t\tawaitPromise: false,\n\t\t\t\t});\n\n\t\t\t\tconst role = result.type === 'success' && result.result?.type === 'string'\n\t\t\t\t\t? (result.result as { value: string }).value\n\t\t\t\t\t: '';\n\t\t\t\tlastRole = role;\n\n\t\t\t\tconst matches = role === expected;\n\t\t\t\treturn isNot ? !matches : matches;\n\t\t\t},\n\t\t\t(pass) => {\n\t\t\t\tif (!pass) {\n\t\t\t\t\treturn `Expected element ${isNot ? 'not ' : ''}to have role \"${expected}\", but got \"${lastRole}\"`;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\ttimeout,\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Retry engine for assertions\n// ---------------------------------------------------------------------------\n\n/**\n * Retry an assertion until it passes or times out.\n * Unlike waitFor(), this produces a proper assertion error message.\n */\nasync function retry(\n\tdescription: string,\n\tcheck: () => Promise<boolean>,\n\tformatError: (lastResult: boolean) => string | null,\n\ttimeout: number,\n): Promise<void> {\n\tconst interval = 100;\n\tconst startTime = Date.now();\n\tlet lastResult = false;\n\n\twhile (Date.now() - startTime < timeout) {\n\t\ttry {\n\t\t\tlastResult = await check();\n\t\t\tif (lastResult) return; // Assertion passed\n\t\t} catch {\n\t\t\t// Check threw -- will retry\n\t\t\tlastResult = false;\n\t\t}\n\t\tawait new Promise((r) => setTimeout(r, interval));\n\t}\n\n\t// Final check\n\ttry {\n\t\tlastResult = await check();\n\t\tif (lastResult) return;\n\t} catch {\n\t\tlastResult = false;\n\t}\n\n\tconst errorMsg = formatError(lastResult) ?? `Assertion failed: ${description}`;\n\tthrow new AssertionError(errorMsg);\n}\n\n// ---------------------------------------------------------------------------\n// Custom assertion error\n// ---------------------------------------------------------------------------\n\n/**\n * Error thrown when an assertion fails.\n */\nexport class AssertionError extends Error {\n\treadonly name = 'AssertionError';\n\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t}\n}\n"]}
|