uidex 0.2.0 → 0.2.4
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/README.md +132 -32
- package/claude/audit-command.md +40 -10
- package/claude/rules.md +99 -20
- package/dist/api/index.cjs +254 -0
- package/dist/api/index.cjs.map +1 -0
- package/dist/api/index.d.cts +236 -0
- package/dist/api/index.d.ts +236 -0
- package/dist/api/index.js +226 -0
- package/dist/api/index.js.map +1 -0
- package/dist/core/index.cjs +10149 -2576
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +155 -170
- package/dist/core/index.d.ts +155 -170
- package/dist/core/index.global.js +65920 -2855
- package/dist/core/index.global.js.map +1 -1
- package/dist/core/index.js +10145 -2576
- package/dist/core/index.js.map +1 -1
- package/dist/core/style.css +1170 -612
- package/dist/index.cjs +10129 -2536
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -8
- package/dist/index.d.ts +43 -8
- package/dist/index.js +10132 -2541
- package/dist/index.js.map +1 -1
- package/dist/playwright/index.cjs.map +1 -1
- package/dist/playwright/index.d.cts +2 -2
- package/dist/playwright/index.d.ts +2 -2
- package/dist/playwright/index.js.map +1 -1
- package/dist/playwright/reporter.cjs.map +1 -1
- package/dist/playwright/reporter.js.map +1 -1
- package/dist/react/index.cjs +10129 -2536
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +43 -8
- package/dist/react/index.d.ts +43 -8
- package/dist/react/index.js +10132 -2541
- package/dist/react/index.js.map +1 -1
- package/dist/scripts/cli.cjs +3237 -500
- package/package.json +20 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/playwright/index.ts","../../src/playwright/fixture.ts"],"sourcesContent":["import type { Page, Locator } from '@playwright/test';\n\n/** The data attribute used for uidex component selectors. */\nexport const UIDEX_ATTR = 'data-uidex';\n\n/** Build a CSS selector for a uidex-annotated element. */\nexport function uidexSelector(id: string): string {\n return `[${UIDEX_ATTR}=\"${id}\"]`;\n}\n\n/** Attachment name used to pass coverage data from fixture to reporter. */\nexport const COVERAGE_ATTACHMENT = 'uidex-coverage';\n\n// Fixture — provides `uidex` as a Playwright test fixture with coverage tracking\nexport { test, expect } from './fixture';\nexport type { UidexLocator, UidexFixtures } from './fixture';\n\n/**\n * Create a Playwright locator for a uidex-annotated element.\n *\n * @example\n * ```ts\n * import { uidex } from 'uidex/playwright';\n *\n * test('submit form', async ({ page }) => {\n * await uidex(page, 'submit-btn').click();\n * });\n * ```\n */\nexport function uidex(page: Page, id: string): Locator {\n return page.locator(uidexSelector(id));\n}\n\n/**\n * Create a typed locator factory bound to a Page instance.\n * When used with the generated ComponentId type, provides autocomplete\n * for all annotated component IDs.\n *\n * @example\n * ```ts\n * import { createUidexLocators } from 'uidex/playwright';\n * import type { ComponentId } from './uidex.gen.test';\n *\n * test('checkout flow', async ({ page }) => {\n * const u = createUidexLocators<ComponentId>(page);\n * await u('cart-summary').waitFor(); // autocomplete + type checking\n * await u('checkout-btn').click();\n * });\n * ```\n */\nexport function createUidexLocators<T extends string = string>(\n page: Page
|
|
1
|
+
{"version":3,"sources":["../../src/playwright/index.ts","../../src/playwright/fixture.ts"],"sourcesContent":["import type { Page, Locator } from '@playwright/test';\n\n/** The data attribute used for uidex component selectors. */\nexport const UIDEX_ATTR = 'data-uidex';\n\n/** Build a CSS selector for a uidex-annotated element. */\nexport function uidexSelector(id: string): string {\n return `[${UIDEX_ATTR}=\"${id}\"]`;\n}\n\n/** Attachment name used to pass coverage data from fixture to reporter. */\nexport const COVERAGE_ATTACHMENT = 'uidex-coverage';\n\n// Fixture — provides `uidex` as a Playwright test fixture with coverage tracking\nexport { test, expect } from './fixture';\nexport type { UidexLocator, UidexFixtures } from './fixture';\n\n/**\n * Create a Playwright locator for a uidex-annotated element.\n *\n * @example\n * ```ts\n * import { uidex } from 'uidex/playwright';\n *\n * test('submit form', async ({ page }) => {\n * await uidex(page, 'submit-btn').click();\n * });\n * ```\n */\nexport function uidex(page: Page, id: string): Locator {\n return page.locator(uidexSelector(id));\n}\n\n/**\n * Create a typed locator factory bound to a Page instance.\n * When used with the generated ComponentId type, provides autocomplete\n * for all annotated component IDs.\n *\n * @example\n * ```ts\n * import { createUidexLocators } from 'uidex/playwright';\n * import type { ComponentId } from './uidex.gen.test';\n *\n * test('checkout flow', async ({ page }) => {\n * const u = createUidexLocators<ComponentId>(page);\n * await u('cart-summary').waitFor(); // autocomplete + type checking\n * await u('checkout-btn').click();\n * });\n * ```\n */\nexport function createUidexLocators<T extends string = string>(\n page: Page\n): (id: T) => Locator {\n return (id: T) => page.locator(uidexSelector(id));\n}\n","import { test as base, expect } from '@playwright/test';\nimport type { Locator } from '@playwright/test';\nimport { uidexSelector, COVERAGE_ATTACHMENT } from './index';\n\ntype UidexLocator<T extends string = string> = (id: T) => Locator;\n\ninterface UidexFixtures {\n /**\n * Create a Playwright locator for a uidex-annotated element.\n * Automatically tracks usage for the coverage reporter.\n *\n * @example\n * ```ts\n * test('add todo', async ({ uidex }) => {\n * await uidex('todo-input').fill('Buy milk');\n * await uidex('todo-add-button').click();\n * });\n * ```\n */\n uidex: UidexLocator;\n}\n\nexport const test = base.extend<UidexFixtures>({\n uidex: async ({ page }, use, testInfo) => {\n const used = new Set<string>();\n\n const locator: UidexLocator = (id: string) => {\n used.add(id);\n return page.locator(uidexSelector(id));\n };\n\n await use(locator);\n\n // Attach coverage data for the reporter to collect\n await testInfo.attach(COVERAGE_ATTACHMENT, {\n body: JSON.stringify([...used]),\n contentType: 'application/json',\n });\n },\n});\n\nexport { expect };\nexport type { UidexLocator, UidexFixtures };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAqC;AAsB9B,IAAM,OAAO,YAAAA,KAAK,OAAsB;AAAA,EAC7C,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK,aAAa;AACxC,UAAM,OAAO,oBAAI,IAAY;AAE7B,UAAM,UAAwB,CAAC,OAAe;AAC5C,WAAK,IAAI,EAAE;AACX,aAAO,KAAK,QAAQ,cAAc,EAAE,CAAC;AAAA,IACvC;AAEA,UAAM,IAAI,OAAO;AAGjB,UAAM,SAAS,OAAO,qBAAqB;AAAA,MACzC,MAAM,KAAK,UAAU,CAAC,GAAG,IAAI,CAAC;AAAA,MAC9B,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AACF,CAAC;;;ADpCM,IAAM,aAAa;AAGnB,SAAS,cAAc,IAAoB;AAChD,SAAO,IAAI,UAAU,KAAK,EAAE;AAC9B;AAGO,IAAM,sBAAsB;AAkB5B,SAAS,MAAM,MAAY,IAAqB;AACrD,SAAO,KAAK,QAAQ,cAAc,EAAE,CAAC;AACvC;AAmBO,SAAS,oBACd,MACoB;AACpB,SAAO,CAAC,OAAU,KAAK,QAAQ,cAAc,EAAE,CAAC;AAClD;","names":["base"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import * as _playwright_test from '@playwright/test';
|
|
1
2
|
import { Locator, Page } from '@playwright/test';
|
|
2
3
|
export { expect } from '@playwright/test';
|
|
3
|
-
import * as playwright_test from 'playwright/test';
|
|
4
4
|
|
|
5
5
|
type UidexLocator<T extends string = string> = (id: T) => Locator;
|
|
6
6
|
interface UidexFixtures {
|
|
@@ -18,7 +18,7 @@ interface UidexFixtures {
|
|
|
18
18
|
*/
|
|
19
19
|
uidex: UidexLocator;
|
|
20
20
|
}
|
|
21
|
-
declare const test:
|
|
21
|
+
declare const test: _playwright_test.TestType<_playwright_test.PlaywrightTestArgs & _playwright_test.PlaywrightTestOptions & UidexFixtures, _playwright_test.PlaywrightWorkerArgs & _playwright_test.PlaywrightWorkerOptions>;
|
|
22
22
|
|
|
23
23
|
/** The data attribute used for uidex component selectors. */
|
|
24
24
|
declare const UIDEX_ATTR = "data-uidex";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import * as _playwright_test from '@playwright/test';
|
|
1
2
|
import { Locator, Page } from '@playwright/test';
|
|
2
3
|
export { expect } from '@playwright/test';
|
|
3
|
-
import * as playwright_test from 'playwright/test';
|
|
4
4
|
|
|
5
5
|
type UidexLocator<T extends string = string> = (id: T) => Locator;
|
|
6
6
|
interface UidexFixtures {
|
|
@@ -18,7 +18,7 @@ interface UidexFixtures {
|
|
|
18
18
|
*/
|
|
19
19
|
uidex: UidexLocator;
|
|
20
20
|
}
|
|
21
|
-
declare const test:
|
|
21
|
+
declare const test: _playwright_test.TestType<_playwright_test.PlaywrightTestArgs & _playwright_test.PlaywrightTestOptions & UidexFixtures, _playwright_test.PlaywrightWorkerArgs & _playwright_test.PlaywrightWorkerOptions>;
|
|
22
22
|
|
|
23
23
|
/** The data attribute used for uidex component selectors. */
|
|
24
24
|
declare const UIDEX_ATTR = "data-uidex";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/playwright/fixture.ts","../../src/playwright/index.ts"],"sourcesContent":["import { test as base, expect } from '@playwright/test';\nimport type { Locator } from '@playwright/test';\nimport { uidexSelector, COVERAGE_ATTACHMENT } from './index';\n\ntype UidexLocator<T extends string = string> = (id: T) => Locator;\n\ninterface UidexFixtures {\n /**\n * Create a Playwright locator for a uidex-annotated element.\n * Automatically tracks usage for the coverage reporter.\n *\n * @example\n * ```ts\n * test('add todo', async ({ uidex }) => {\n * await uidex('todo-input').fill('Buy milk');\n * await uidex('todo-add-button').click();\n * });\n * ```\n */\n uidex: UidexLocator;\n}\n\nexport const test = base.extend<UidexFixtures>({\n uidex: async ({ page }, use, testInfo) => {\n const used = new Set<string>();\n\n const locator: UidexLocator = (id: string) => {\n used.add(id);\n return page.locator(uidexSelector(id));\n };\n\n await use(locator);\n\n // Attach coverage data for the reporter to collect\n await testInfo.attach(COVERAGE_ATTACHMENT, {\n body: JSON.stringify([...used]),\n contentType: 'application/json',\n });\n },\n});\n\nexport { expect };\nexport type { UidexLocator, UidexFixtures };\n","import type { Page, Locator } from '@playwright/test';\n\n/** The data attribute used for uidex component selectors. */\nexport const UIDEX_ATTR = 'data-uidex';\n\n/** Build a CSS selector for a uidex-annotated element. */\nexport function uidexSelector(id: string): string {\n return `[${UIDEX_ATTR}=\"${id}\"]`;\n}\n\n/** Attachment name used to pass coverage data from fixture to reporter. */\nexport const COVERAGE_ATTACHMENT = 'uidex-coverage';\n\n// Fixture — provides `uidex` as a Playwright test fixture with coverage tracking\nexport { test, expect } from './fixture';\nexport type { UidexLocator, UidexFixtures } from './fixture';\n\n/**\n * Create a Playwright locator for a uidex-annotated element.\n *\n * @example\n * ```ts\n * import { uidex } from 'uidex/playwright';\n *\n * test('submit form', async ({ page }) => {\n * await uidex(page, 'submit-btn').click();\n * });\n * ```\n */\nexport function uidex(page: Page, id: string): Locator {\n return page.locator(uidexSelector(id));\n}\n\n/**\n * Create a typed locator factory bound to a Page instance.\n * When used with the generated ComponentId type, provides autocomplete\n * for all annotated component IDs.\n *\n * @example\n * ```ts\n * import { createUidexLocators } from 'uidex/playwright';\n * import type { ComponentId } from './uidex.gen.test';\n *\n * test('checkout flow', async ({ page }) => {\n * const u = createUidexLocators<ComponentId>(page);\n * await u('cart-summary').waitFor(); // autocomplete + type checking\n * await u('checkout-btn').click();\n * });\n * ```\n */\nexport function createUidexLocators<T extends string = string>(\n page: Page
|
|
1
|
+
{"version":3,"sources":["../../src/playwright/fixture.ts","../../src/playwright/index.ts"],"sourcesContent":["import { test as base, expect } from '@playwright/test';\nimport type { Locator } from '@playwright/test';\nimport { uidexSelector, COVERAGE_ATTACHMENT } from './index';\n\ntype UidexLocator<T extends string = string> = (id: T) => Locator;\n\ninterface UidexFixtures {\n /**\n * Create a Playwright locator for a uidex-annotated element.\n * Automatically tracks usage for the coverage reporter.\n *\n * @example\n * ```ts\n * test('add todo', async ({ uidex }) => {\n * await uidex('todo-input').fill('Buy milk');\n * await uidex('todo-add-button').click();\n * });\n * ```\n */\n uidex: UidexLocator;\n}\n\nexport const test = base.extend<UidexFixtures>({\n uidex: async ({ page }, use, testInfo) => {\n const used = new Set<string>();\n\n const locator: UidexLocator = (id: string) => {\n used.add(id);\n return page.locator(uidexSelector(id));\n };\n\n await use(locator);\n\n // Attach coverage data for the reporter to collect\n await testInfo.attach(COVERAGE_ATTACHMENT, {\n body: JSON.stringify([...used]),\n contentType: 'application/json',\n });\n },\n});\n\nexport { expect };\nexport type { UidexLocator, UidexFixtures };\n","import type { Page, Locator } from '@playwright/test';\n\n/** The data attribute used for uidex component selectors. */\nexport const UIDEX_ATTR = 'data-uidex';\n\n/** Build a CSS selector for a uidex-annotated element. */\nexport function uidexSelector(id: string): string {\n return `[${UIDEX_ATTR}=\"${id}\"]`;\n}\n\n/** Attachment name used to pass coverage data from fixture to reporter. */\nexport const COVERAGE_ATTACHMENT = 'uidex-coverage';\n\n// Fixture — provides `uidex` as a Playwright test fixture with coverage tracking\nexport { test, expect } from './fixture';\nexport type { UidexLocator, UidexFixtures } from './fixture';\n\n/**\n * Create a Playwright locator for a uidex-annotated element.\n *\n * @example\n * ```ts\n * import { uidex } from 'uidex/playwright';\n *\n * test('submit form', async ({ page }) => {\n * await uidex(page, 'submit-btn').click();\n * });\n * ```\n */\nexport function uidex(page: Page, id: string): Locator {\n return page.locator(uidexSelector(id));\n}\n\n/**\n * Create a typed locator factory bound to a Page instance.\n * When used with the generated ComponentId type, provides autocomplete\n * for all annotated component IDs.\n *\n * @example\n * ```ts\n * import { createUidexLocators } from 'uidex/playwright';\n * import type { ComponentId } from './uidex.gen.test';\n *\n * test('checkout flow', async ({ page }) => {\n * const u = createUidexLocators<ComponentId>(page);\n * await u('cart-summary').waitFor(); // autocomplete + type checking\n * await u('checkout-btn').click();\n * });\n * ```\n */\nexport function createUidexLocators<T extends string = string>(\n page: Page\n): (id: T) => Locator {\n return (id: T) => page.locator(uidexSelector(id));\n}\n"],"mappings":";AAAA,SAAS,QAAQ,MAAM,cAAc;AAsB9B,IAAM,OAAO,KAAK,OAAsB;AAAA,EAC7C,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK,aAAa;AACxC,UAAM,OAAO,oBAAI,IAAY;AAE7B,UAAM,UAAwB,CAAC,OAAe;AAC5C,WAAK,IAAI,EAAE;AACX,aAAO,KAAK,QAAQ,cAAc,EAAE,CAAC;AAAA,IACvC;AAEA,UAAM,IAAI,OAAO;AAGjB,UAAM,SAAS,OAAO,qBAAqB;AAAA,MACzC,MAAM,KAAK,UAAU,CAAC,GAAG,IAAI,CAAC;AAAA,MAC9B,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AACF,CAAC;;;ACpCM,IAAM,aAAa;AAGnB,SAAS,cAAc,IAAoB;AAChD,SAAO,IAAI,UAAU,KAAK,EAAE;AAC9B;AAGO,IAAM,sBAAsB;AAkB5B,SAAS,MAAM,MAAY,IAAqB;AACrD,SAAO,KAAK,QAAQ,cAAc,EAAE,CAAC;AACvC;AAmBO,SAAS,oBACd,MACoB;AACpB,SAAO,CAAC,OAAU,KAAK,QAAQ,cAAc,EAAE,CAAC;AAClD;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/playwright/reporter.ts","../../src/playwright/index.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n Reporter,\n FullResult,\n TestCase,\n TestResult,\n} from '@playwright/test/reporter';\nimport { COVERAGE_ATTACHMENT } from './index';\n\nexport interface UidexCoverageOptions {\n /** All known component IDs — pass componentIds from uidex.gen.test.ts */\n componentIds: readonly string[];\n /** Output file path for JSON report (default: \"uidex-coverage.json\") */\n outputPath?: string;\n}\n\nexport interface UidexCoverageReport {\n covered: string[];\n uncovered: string[];\n total: number;\n percentage: number;\n}\n\nclass UidexCoverageReporter implements Reporter {\n private interacted = new Set<string>();\n private componentIds: readonly string[];\n private outputPath: string;\n\n constructor(options: UidexCoverageOptions) {\n this.componentIds = options.componentIds ?? [];\n this.outputPath = options.outputPath ?? 'uidex-coverage.json';\n }\n\n onTestEnd(_test: TestCase, result: TestResult) {\n for (const attachment of result.attachments) {\n if (attachment.name === COVERAGE_ATTACHMENT && attachment.body) {\n const ids: string[] = JSON.parse(attachment.body.toString());\n for (const id of ids) {\n this.interacted.add(id);\n }\n }\n }\n }\n\n onEnd(_result: FullResult) {\n const all = [...this.componentIds];\n const covered = all.filter((id) => this.interacted.has(id)).sort();\n const uncovered = all.filter((id) => !this.interacted.has(id)).sort();\n const total = all.length;\n const percentage =\n total > 0 ? Math.round((covered.length / total) * 100) : 0;\n\n // Console summary\n console.log('');\n console.log(\n `uidex coverage: ${covered.length}/${total} components (${percentage}%)
|
|
1
|
+
{"version":3,"sources":["../../src/playwright/reporter.ts","../../src/playwright/index.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n Reporter,\n FullResult,\n TestCase,\n TestResult,\n} from '@playwright/test/reporter';\nimport { COVERAGE_ATTACHMENT } from './index';\n\nexport interface UidexCoverageOptions {\n /** All known component IDs — pass componentIds from uidex.gen.test.ts */\n componentIds: readonly string[];\n /** Output file path for JSON report (default: \"uidex-coverage.json\") */\n outputPath?: string;\n}\n\nexport interface UidexCoverageReport {\n covered: string[];\n uncovered: string[];\n total: number;\n percentage: number;\n}\n\nclass UidexCoverageReporter implements Reporter {\n private interacted = new Set<string>();\n private componentIds: readonly string[];\n private outputPath: string;\n\n constructor(options: UidexCoverageOptions) {\n this.componentIds = options.componentIds ?? [];\n this.outputPath = options.outputPath ?? 'uidex-coverage.json';\n }\n\n onTestEnd(_test: TestCase, result: TestResult) {\n for (const attachment of result.attachments) {\n if (attachment.name === COVERAGE_ATTACHMENT && attachment.body) {\n const ids: string[] = JSON.parse(attachment.body.toString());\n for (const id of ids) {\n this.interacted.add(id);\n }\n }\n }\n }\n\n onEnd(_result: FullResult) {\n const all = [...this.componentIds];\n const covered = all.filter((id) => this.interacted.has(id)).sort();\n const uncovered = all.filter((id) => !this.interacted.has(id)).sort();\n const total = all.length;\n const percentage =\n total > 0 ? Math.round((covered.length / total) * 100) : 0;\n\n // Console summary\n console.log('');\n console.log(\n `uidex coverage: ${covered.length}/${total} components (${percentage}%)`\n );\n if (uncovered.length > 0) {\n console.log(` uncovered: ${uncovered.join(', ')}`);\n }\n console.log('');\n\n // JSON report\n const report: UidexCoverageReport = {\n covered,\n uncovered,\n total,\n percentage,\n };\n fs.writeFileSync(\n path.resolve(process.cwd(), this.outputPath),\n JSON.stringify(report, null, 2) + '\\n'\n );\n }\n}\n\nexport default UidexCoverageReporter;\n","import type { Page, Locator } from '@playwright/test';\n\n/** The data attribute used for uidex component selectors. */\nexport const UIDEX_ATTR = 'data-uidex';\n\n/** Build a CSS selector for a uidex-annotated element. */\nexport function uidexSelector(id: string): string {\n return `[${UIDEX_ATTR}=\"${id}\"]`;\n}\n\n/** Attachment name used to pass coverage data from fixture to reporter. */\nexport const COVERAGE_ATTACHMENT = 'uidex-coverage';\n\n// Fixture — provides `uidex` as a Playwright test fixture with coverage tracking\nexport { test, expect } from './fixture';\nexport type { UidexLocator, UidexFixtures } from './fixture';\n\n/**\n * Create a Playwright locator for a uidex-annotated element.\n *\n * @example\n * ```ts\n * import { uidex } from 'uidex/playwright';\n *\n * test('submit form', async ({ page }) => {\n * await uidex(page, 'submit-btn').click();\n * });\n * ```\n */\nexport function uidex(page: Page, id: string): Locator {\n return page.locator(uidexSelector(id));\n}\n\n/**\n * Create a typed locator factory bound to a Page instance.\n * When used with the generated ComponentId type, provides autocomplete\n * for all annotated component IDs.\n *\n * @example\n * ```ts\n * import { createUidexLocators } from 'uidex/playwright';\n * import type { ComponentId } from './uidex.gen.test';\n *\n * test('checkout flow', async ({ page }) => {\n * const u = createUidexLocators<ComponentId>(page);\n * await u('cart-summary').waitFor(); // autocomplete + type checking\n * await u('checkout-btn').click();\n * });\n * ```\n */\nexport function createUidexLocators<T extends string = string>(\n page: Page\n): (id: T) => Locator {\n return (id: T) => page.locator(uidexSelector(id));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAoB;AACpB,WAAsB;;;ACUf,IAAM,sBAAsB;;;ADanC,IAAM,wBAAN,MAAgD;AAAA,EACtC,aAAa,oBAAI,IAAY;AAAA,EAC7B;AAAA,EACA;AAAA,EAER,YAAY,SAA+B;AACzC,SAAK,eAAe,QAAQ,gBAAgB,CAAC;AAC7C,SAAK,aAAa,QAAQ,cAAc;AAAA,EAC1C;AAAA,EAEA,UAAU,OAAiB,QAAoB;AAC7C,eAAW,cAAc,OAAO,aAAa;AAC3C,UAAI,WAAW,SAAS,uBAAuB,WAAW,MAAM;AAC9D,cAAM,MAAgB,KAAK,MAAM,WAAW,KAAK,SAAS,CAAC;AAC3D,mBAAW,MAAM,KAAK;AACpB,eAAK,WAAW,IAAI,EAAE;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAqB;AACzB,UAAM,MAAM,CAAC,GAAG,KAAK,YAAY;AACjC,UAAM,UAAU,IAAI,OAAO,CAAC,OAAO,KAAK,WAAW,IAAI,EAAE,CAAC,EAAE,KAAK;AACjE,UAAM,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,WAAW,IAAI,EAAE,CAAC,EAAE,KAAK;AACpE,UAAM,QAAQ,IAAI;AAClB,UAAM,aACJ,QAAQ,IAAI,KAAK,MAAO,QAAQ,SAAS,QAAS,GAAG,IAAI;AAG3D,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,mBAAmB,QAAQ,MAAM,IAAI,KAAK,gBAAgB,UAAU;AAAA,IACtE;AACA,QAAI,UAAU,SAAS,GAAG;AACxB,cAAQ,IAAI,gBAAgB,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,IACpD;AACA,YAAQ,IAAI,EAAE;AAGd,UAAM,SAA8B;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,IAAG;AAAA,MACI,aAAQ,QAAQ,IAAI,GAAG,KAAK,UAAU;AAAA,MAC3C,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI;AAAA,IACpC;AAAA,EACF;AACF;AAEA,IAAO,mBAAQ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/playwright/reporter.ts","../../src/playwright/index.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n Reporter,\n FullResult,\n TestCase,\n TestResult,\n} from '@playwright/test/reporter';\nimport { COVERAGE_ATTACHMENT } from './index';\n\nexport interface UidexCoverageOptions {\n /** All known component IDs — pass componentIds from uidex.gen.test.ts */\n componentIds: readonly string[];\n /** Output file path for JSON report (default: \"uidex-coverage.json\") */\n outputPath?: string;\n}\n\nexport interface UidexCoverageReport {\n covered: string[];\n uncovered: string[];\n total: number;\n percentage: number;\n}\n\nclass UidexCoverageReporter implements Reporter {\n private interacted = new Set<string>();\n private componentIds: readonly string[];\n private outputPath: string;\n\n constructor(options: UidexCoverageOptions) {\n this.componentIds = options.componentIds ?? [];\n this.outputPath = options.outputPath ?? 'uidex-coverage.json';\n }\n\n onTestEnd(_test: TestCase, result: TestResult) {\n for (const attachment of result.attachments) {\n if (attachment.name === COVERAGE_ATTACHMENT && attachment.body) {\n const ids: string[] = JSON.parse(attachment.body.toString());\n for (const id of ids) {\n this.interacted.add(id);\n }\n }\n }\n }\n\n onEnd(_result: FullResult) {\n const all = [...this.componentIds];\n const covered = all.filter((id) => this.interacted.has(id)).sort();\n const uncovered = all.filter((id) => !this.interacted.has(id)).sort();\n const total = all.length;\n const percentage =\n total > 0 ? Math.round((covered.length / total) * 100) : 0;\n\n // Console summary\n console.log('');\n console.log(\n `uidex coverage: ${covered.length}/${total} components (${percentage}%)
|
|
1
|
+
{"version":3,"sources":["../../src/playwright/reporter.ts","../../src/playwright/index.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n Reporter,\n FullResult,\n TestCase,\n TestResult,\n} from '@playwright/test/reporter';\nimport { COVERAGE_ATTACHMENT } from './index';\n\nexport interface UidexCoverageOptions {\n /** All known component IDs — pass componentIds from uidex.gen.test.ts */\n componentIds: readonly string[];\n /** Output file path for JSON report (default: \"uidex-coverage.json\") */\n outputPath?: string;\n}\n\nexport interface UidexCoverageReport {\n covered: string[];\n uncovered: string[];\n total: number;\n percentage: number;\n}\n\nclass UidexCoverageReporter implements Reporter {\n private interacted = new Set<string>();\n private componentIds: readonly string[];\n private outputPath: string;\n\n constructor(options: UidexCoverageOptions) {\n this.componentIds = options.componentIds ?? [];\n this.outputPath = options.outputPath ?? 'uidex-coverage.json';\n }\n\n onTestEnd(_test: TestCase, result: TestResult) {\n for (const attachment of result.attachments) {\n if (attachment.name === COVERAGE_ATTACHMENT && attachment.body) {\n const ids: string[] = JSON.parse(attachment.body.toString());\n for (const id of ids) {\n this.interacted.add(id);\n }\n }\n }\n }\n\n onEnd(_result: FullResult) {\n const all = [...this.componentIds];\n const covered = all.filter((id) => this.interacted.has(id)).sort();\n const uncovered = all.filter((id) => !this.interacted.has(id)).sort();\n const total = all.length;\n const percentage =\n total > 0 ? Math.round((covered.length / total) * 100) : 0;\n\n // Console summary\n console.log('');\n console.log(\n `uidex coverage: ${covered.length}/${total} components (${percentage}%)`\n );\n if (uncovered.length > 0) {\n console.log(` uncovered: ${uncovered.join(', ')}`);\n }\n console.log('');\n\n // JSON report\n const report: UidexCoverageReport = {\n covered,\n uncovered,\n total,\n percentage,\n };\n fs.writeFileSync(\n path.resolve(process.cwd(), this.outputPath),\n JSON.stringify(report, null, 2) + '\\n'\n );\n }\n}\n\nexport default UidexCoverageReporter;\n","import type { Page, Locator } from '@playwright/test';\n\n/** The data attribute used for uidex component selectors. */\nexport const UIDEX_ATTR = 'data-uidex';\n\n/** Build a CSS selector for a uidex-annotated element. */\nexport function uidexSelector(id: string): string {\n return `[${UIDEX_ATTR}=\"${id}\"]`;\n}\n\n/** Attachment name used to pass coverage data from fixture to reporter. */\nexport const COVERAGE_ATTACHMENT = 'uidex-coverage';\n\n// Fixture — provides `uidex` as a Playwright test fixture with coverage tracking\nexport { test, expect } from './fixture';\nexport type { UidexLocator, UidexFixtures } from './fixture';\n\n/**\n * Create a Playwright locator for a uidex-annotated element.\n *\n * @example\n * ```ts\n * import { uidex } from 'uidex/playwright';\n *\n * test('submit form', async ({ page }) => {\n * await uidex(page, 'submit-btn').click();\n * });\n * ```\n */\nexport function uidex(page: Page, id: string): Locator {\n return page.locator(uidexSelector(id));\n}\n\n/**\n * Create a typed locator factory bound to a Page instance.\n * When used with the generated ComponentId type, provides autocomplete\n * for all annotated component IDs.\n *\n * @example\n * ```ts\n * import { createUidexLocators } from 'uidex/playwright';\n * import type { ComponentId } from './uidex.gen.test';\n *\n * test('checkout flow', async ({ page }) => {\n * const u = createUidexLocators<ComponentId>(page);\n * await u('cart-summary').waitFor(); // autocomplete + type checking\n * await u('checkout-btn').click();\n * });\n * ```\n */\nexport function createUidexLocators<T extends string = string>(\n page: Page\n): (id: T) => Locator {\n return (id: T) => page.locator(uidexSelector(id));\n}\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,YAAY,UAAU;;;ACUf,IAAM,sBAAsB;;;ADanC,IAAM,wBAAN,MAAgD;AAAA,EACtC,aAAa,oBAAI,IAAY;AAAA,EAC7B;AAAA,EACA;AAAA,EAER,YAAY,SAA+B;AACzC,SAAK,eAAe,QAAQ,gBAAgB,CAAC;AAC7C,SAAK,aAAa,QAAQ,cAAc;AAAA,EAC1C;AAAA,EAEA,UAAU,OAAiB,QAAoB;AAC7C,eAAW,cAAc,OAAO,aAAa;AAC3C,UAAI,WAAW,SAAS,uBAAuB,WAAW,MAAM;AAC9D,cAAM,MAAgB,KAAK,MAAM,WAAW,KAAK,SAAS,CAAC;AAC3D,mBAAW,MAAM,KAAK;AACpB,eAAK,WAAW,IAAI,EAAE;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAqB;AACzB,UAAM,MAAM,CAAC,GAAG,KAAK,YAAY;AACjC,UAAM,UAAU,IAAI,OAAO,CAAC,OAAO,KAAK,WAAW,IAAI,EAAE,CAAC,EAAE,KAAK;AACjE,UAAM,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,WAAW,IAAI,EAAE,CAAC,EAAE,KAAK;AACpE,UAAM,QAAQ,IAAI;AAClB,UAAM,aACJ,QAAQ,IAAI,KAAK,MAAO,QAAQ,SAAS,QAAS,GAAG,IAAI;AAG3D,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,mBAAmB,QAAQ,MAAM,IAAI,KAAK,gBAAgB,UAAU;AAAA,IACtE;AACA,QAAI,UAAU,SAAS,GAAG;AACxB,cAAQ,IAAI,gBAAgB,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,IACpD;AACA,YAAQ,IAAI,EAAE;AAGd,UAAM,SAA8B;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,IAAG;AAAA,MACI,aAAQ,QAAQ,IAAI,GAAG,KAAK,UAAU;AAAA,MAC3C,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI;AAAA,IACpC;AAAA,EACF;AACF;AAEA,IAAO,mBAAQ;","names":[]}
|