@tft/crispr-forms-testing 21.0.13 → 21.0.15

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.
Files changed (39) hide show
  1. package/README.md +163 -0
  2. package/field-tests/autocomplete-chiplist.tests.d.ts +1 -1
  3. package/field-tests/autocomplete-chiplist.tests.js +25 -22
  4. package/field-tests/autocomplete-chiplist.tests.js.map +1 -1
  5. package/field-tests/autocomplete.tests.d.ts +1 -1
  6. package/field-tests/autocomplete.tests.js +22 -19
  7. package/field-tests/autocomplete.tests.js.map +1 -1
  8. package/field-tests/checkbox.tests.d.ts +1 -1
  9. package/field-tests/checkbox.tests.js +18 -15
  10. package/field-tests/checkbox.tests.js.map +1 -1
  11. package/field-tests/datepicker.tests.d.ts +1 -1
  12. package/field-tests/datepicker.tests.js +18 -15
  13. package/field-tests/datepicker.tests.js.map +1 -1
  14. package/field-tests/field-test-factory.d.ts +1 -1
  15. package/field-tests/field-test-factory.js +28 -24
  16. package/field-tests/field-test-factory.js.map +1 -1
  17. package/field-tests/file-upload.tests.d.ts +1 -1
  18. package/field-tests/file-upload.tests.js +15 -12
  19. package/field-tests/file-upload.tests.js.map +1 -1
  20. package/field-tests/input.tests.d.ts +1 -1
  21. package/field-tests/input.tests.js +39 -36
  22. package/field-tests/input.tests.js.map +1 -1
  23. package/field-tests/select.tests.d.ts +1 -1
  24. package/field-tests/select.tests.js +21 -18
  25. package/field-tests/select.tests.js.map +1 -1
  26. package/field-tests/slider.tests.d.ts +1 -1
  27. package/field-tests/slider.tests.js +13 -10
  28. package/field-tests/slider.tests.js.map +1 -1
  29. package/field-tests/textarea.tests.d.ts +1 -1
  30. package/field-tests/textarea.tests.js +15 -12
  31. package/field-tests/textarea.tests.js.map +1 -1
  32. package/field-tests/unit-conversion.tests.d.ts +1 -1
  33. package/field-tests/unit-conversion.tests.js +13 -10
  34. package/field-tests/unit-conversion.tests.js.map +1 -1
  35. package/helpers/form.helpers.js +34 -16
  36. package/helpers/form.helpers.js.map +1 -1
  37. package/index.js +30 -14
  38. package/index.js.map +1 -1
  39. package/package.json +6 -1
@@ -1,3 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMatFormField = getMatFormField;
4
+ exports.getInput = getInput;
5
+ exports.getError = getError;
6
+ exports.getLabel = getLabel;
7
+ exports.getHint = getHint;
8
+ exports.touchInput = touchInput;
9
+ exports.getMatSelect = getMatSelect;
10
+ exports.openSelect = openSelect;
11
+ exports.selectOption = selectOption;
12
+ exports.touchSelect = touchSelect;
13
+ exports.getCheckbox = getCheckbox;
14
+ exports.touchCheckbox = touchCheckbox;
15
+ exports.getAutocompleteInput = getAutocompleteInput;
16
+ exports.touchAutocomplete = touchAutocomplete;
17
+ exports.submitForm = submitForm;
18
+ exports.touchDatepicker = touchDatepicker;
1
19
  /**
2
20
  * Returns the locator for a field's root element (the element with `data-testid`).
3
21
  * For most fields this is a `mat-form-field`; for checkbox/slider it is the control element.
@@ -6,14 +24,14 @@
6
24
  * - subGroup child: `'address.city'`
7
25
  * - formGroupList item child: `'contacts[0].email'`
8
26
  */
9
- export function getMatFormField(page, testId) {
27
+ function getMatFormField(page, testId) {
10
28
  return page.locator(`[data-testid="${testId}"]`);
11
29
  }
12
30
  /**
13
31
  * Returns the `<input>` inside a field. Works for INPUT, DATEPICKER, and other fields
14
32
  * that render a single native input.
15
33
  */
16
- export function getInput(page, testId) {
34
+ function getInput(page, testId) {
17
35
  return getMatFormField(page, testId).locator('input');
18
36
  }
19
37
  /**
@@ -27,39 +45,39 @@ export function getInput(page, testId) {
27
45
  * e.g. `'input'`, `'select'`, `'autocomplete'`, `'autocomplete-chiplist'`,
28
46
  * `'checkbox'`, `'datepicker'`, `'textarea'`, `'slider'`. Defaults to `'input'`.
29
47
  */
30
- export function getError(page, testId, fieldType = 'input') {
48
+ function getError(page, testId, fieldType = 'input') {
31
49
  return page.locator(`crispr-${fieldType}-field:has([data-testid="${testId}"]) p.tft-control-error`);
32
50
  }
33
51
  /**
34
52
  * Returns the `<mat-label>` element inside a field's form field.
35
53
  */
36
- export function getLabel(page, testId) {
54
+ function getLabel(page, testId) {
37
55
  return getMatFormField(page, testId).locator('mat-label');
38
56
  }
39
57
  /**
40
58
  * Returns the `<mat-hint>` element inside a field's form field.
41
59
  */
42
- export function getHint(page, testId) {
60
+ function getHint(page, testId) {
43
61
  return getMatFormField(page, testId).locator('mat-hint');
44
62
  }
45
63
  /**
46
64
  * Clicks an input and presses Tab to trigger a real blur event.
47
65
  * Angular's touched state is driven by blur, not just focus-out.
48
66
  */
49
- export async function touchInput(page, testId) {
67
+ async function touchInput(page, testId) {
50
68
  await getInput(page, testId).click();
51
69
  await page.keyboard.press('Tab');
52
70
  }
53
71
  /** Returns the `<mat-select>` element inside a select field. */
54
- export function getMatSelect(page, testId) {
72
+ function getMatSelect(page, testId) {
55
73
  return getMatFormField(page, testId).locator('mat-select');
56
74
  }
57
75
  /** Opens a `mat-select` dropdown. */
58
- export async function openSelect(page, testId) {
76
+ async function openSelect(page, testId) {
59
77
  await getMatSelect(page, testId).click();
60
78
  }
61
79
  /** Opens a `mat-select`, clicks the option with the given label, and waits for it to close. */
62
- export async function selectOption(page, testId, optionLabel) {
80
+ async function selectOption(page, testId, optionLabel) {
63
81
  await openSelect(page, testId);
64
82
  await page.locator('mat-option').filter({ hasText: optionLabel }).click();
65
83
  }
@@ -68,20 +86,20 @@ export async function selectOption(page, testId, optionLabel) {
68
86
  * The extra Tab is required — Escape alone dismisses the panel but does not blur
69
87
  * the trigger element, so `ControlErrorsDirective` never sees a blur event.
70
88
  */
71
- export async function touchSelect(page, testId) {
89
+ async function touchSelect(page, testId) {
72
90
  await openSelect(page, testId);
73
91
  await page.keyboard.press('Escape');
74
92
  await page.keyboard.press('Tab');
75
93
  }
76
94
  /** Returns the `<mat-checkbox>` element for a checkbox field. */
77
- export function getCheckbox(page, testId) {
95
+ function getCheckbox(page, testId) {
78
96
  return page.locator(`[data-testid="${testId}"]`);
79
97
  }
80
98
  /**
81
99
  * Clicks a checkbox twice (check then uncheck) and presses Tab to blur,
82
100
  * leaving it unchecked and touched — useful for triggering `requiredTrue` errors.
83
101
  */
84
- export async function touchCheckbox(page, testId) {
102
+ async function touchCheckbox(page, testId) {
85
103
  await getCheckbox(page, testId).click();
86
104
  await getCheckbox(page, testId).click();
87
105
  await page.keyboard.press('Tab');
@@ -90,11 +108,11 @@ export async function touchCheckbox(page, testId) {
90
108
  * Returns the visible search input for an autocomplete field.
91
109
  * Note: this is the `role="textbox"` input, NOT the hidden `[formControlName]` anchor.
92
110
  */
93
- export function getAutocompleteInput(page, testId) {
111
+ function getAutocompleteInput(page, testId) {
94
112
  return getMatFormField(page, testId).locator('input[type="textbox"]');
95
113
  }
96
114
  /** Clicks the autocomplete input and presses Tab to blur. */
97
- export async function touchAutocomplete(page, testId) {
115
+ async function touchAutocomplete(page, testId) {
98
116
  await getAutocompleteInput(page, testId).click();
99
117
  await page.keyboard.press('Tab');
100
118
  }
@@ -109,14 +127,14 @@ export async function touchAutocomplete(page, testId) {
109
127
  *
110
128
  * @param nth - Zero-based index of the form on the page. Defaults to `0`.
111
129
  */
112
- export async function submitForm(page, nth = 0) {
130
+ async function submitForm(page, nth = 0) {
113
131
  await page.evaluate((n) => {
114
132
  const triggers = document.querySelectorAll('[data-testid="submit-trigger"]');
115
133
  triggers[n]?.click();
116
134
  }, nth);
117
135
  }
118
136
  /** Clicks the datepicker input and presses Tab to blur. */
119
- export async function touchDatepicker(page, testId) {
137
+ async function touchDatepicker(page, testId) {
120
138
  await getMatFormField(page, testId).locator('input').click();
121
139
  await page.keyboard.press('Tab');
122
140
  }
@@ -1 +1 @@
1
- {"version":3,"file":"form.helpers.js","sourceRoot":"","sources":["../../../../libs/crispr-forms-testing/src/helpers/form.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { Page, Locator } from '@playwright/test';\n\n/**\n * Returns the locator for a field's root element (the element with `data-testid`).\n * For most fields this is a `mat-form-field`; for checkbox/slider it is the control element.\n *\n * For nested fields, pass the full hierarchical testId path:\n * - subGroup child: `'address.city'`\n * - formGroupList item child: `'contacts[0].email'`\n */\nexport function getMatFormField(page: Page, testId: string): Locator {\n return page.locator(`[data-testid=\"${testId}\"]`);\n}\n\n/**\n * Returns the `<input>` inside a field. Works for INPUT, DATEPICKER, and other fields\n * that render a single native input.\n */\nexport function getInput(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('input');\n}\n\n/**\n * Returns the validation error paragraph for a field.\n *\n * Targets the inner `<p class=\"tft-control-error\">` rather than the host element to\n * avoid Playwright strict-mode failures on fields like autocomplete/chiplist that\n * render two `tft-control-error` host elements (one for each internal input).\n *\n * @param fieldType - The kebab-case field type used in the component selector,\n * e.g. `'input'`, `'select'`, `'autocomplete'`, `'autocomplete-chiplist'`,\n * `'checkbox'`, `'datepicker'`, `'textarea'`, `'slider'`. Defaults to `'input'`.\n */\nexport function getError(page: Page, testId: string, fieldType = 'input'): Locator {\n return page.locator(`crispr-${fieldType}-field:has([data-testid=\"${testId}\"]) p.tft-control-error`);\n}\n\n/**\n * Returns the `<mat-label>` element inside a field's form field.\n */\nexport function getLabel(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('mat-label');\n}\n\n/**\n * Returns the `<mat-hint>` element inside a field's form field.\n */\nexport function getHint(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('mat-hint');\n}\n\n/**\n * Clicks an input and presses Tab to trigger a real blur event.\n * Angular's touched state is driven by blur, not just focus-out.\n */\nexport async function touchInput(page: Page, testId: string): Promise<void> {\n await getInput(page, testId).click();\n await page.keyboard.press('Tab');\n}\n\n/** Returns the `<mat-select>` element inside a select field. */\nexport function getMatSelect(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('mat-select');\n}\n\n/** Opens a `mat-select` dropdown. */\nexport async function openSelect(page: Page, testId: string): Promise<void> {\n await getMatSelect(page, testId).click();\n}\n\n/** Opens a `mat-select`, clicks the option with the given label, and waits for it to close. */\nexport async function selectOption(page: Page, testId: string, optionLabel: string): Promise<void> {\n await openSelect(page, testId);\n await page.locator('mat-option').filter({ hasText: optionLabel }).click();\n}\n\n/**\n * Opens a `mat-select`, presses Escape, then Tab to blur it.\n * The extra Tab is required — Escape alone dismisses the panel but does not blur\n * the trigger element, so `ControlErrorsDirective` never sees a blur event.\n */\nexport async function touchSelect(page: Page, testId: string): Promise<void> {\n await openSelect(page, testId);\n await page.keyboard.press('Escape');\n await page.keyboard.press('Tab');\n}\n\n/** Returns the `<mat-checkbox>` element for a checkbox field. */\nexport function getCheckbox(page: Page, testId: string): Locator {\n return page.locator(`[data-testid=\"${testId}\"]`);\n}\n\n/**\n * Clicks a checkbox twice (check then uncheck) and presses Tab to blur,\n * leaving it unchecked and touched — useful for triggering `requiredTrue` errors.\n */\nexport async function touchCheckbox(page: Page, testId: string): Promise<void> {\n await getCheckbox(page, testId).click();\n await getCheckbox(page, testId).click();\n await page.keyboard.press('Tab');\n}\n\n/**\n * Returns the visible search input for an autocomplete field.\n * Note: this is the `role=\"textbox\"` input, NOT the hidden `[formControlName]` anchor.\n */\nexport function getAutocompleteInput(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('input[type=\"textbox\"]');\n}\n\n/** Clicks the autocomplete input and presses Tab to blur. */\nexport async function touchAutocomplete(page: Page, testId: string): Promise<void> {\n await getAutocompleteInput(page, testId).click();\n await page.keyboard.press('Tab');\n}\n\n/**\n * Programmatically clicks the hidden crispr-form submit button.\n *\n * This fires both the native `submit` event (required by `ControlErrorsFormDirective`\n * to show errors on untouched controls) and Angular's `ngSubmit` event.\n *\n * Must use `evaluate` + native `.click()` because `display:none` elements\n * have no layout position for Playwright pointer events.\n *\n * @param nth - Zero-based index of the form on the page. Defaults to `0`.\n */\nexport async function submitForm(page: Page, nth = 0): Promise<void> {\n await page.evaluate((n) => {\n const triggers = document.querySelectorAll<HTMLButtonElement>('[data-testid=\"submit-trigger\"]');\n triggers[n]?.click();\n }, nth);\n}\n\n/** Clicks the datepicker input and presses Tab to blur. */\nexport async function touchDatepicker(page: Page, testId: string): Promise<void> {\n await getMatFormField(page, testId).locator('input').click();\n await page.keyboard.press('Tab');\n}\n"]}
1
+ {"version":3,"file":"form.helpers.js","sourceRoot":"","sources":["../../../../libs/crispr-forms-testing/src/helpers/form.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { Page, Locator } from '@playwright/test';\n\n/**\n * Returns the locator for a field's root element (the element with `data-testid`).\n * For most fields this is a `mat-form-field`; for checkbox/slider it is the control element.\n *\n * For nested fields, pass the full hierarchical testId path:\n * - subGroup child: `'address.city'`\n * - formGroupList item child: `'contacts[0].email'`\n */\nexport function getMatFormField(page: Page, testId: string): Locator {\n return page.locator(`[data-testid=\"${testId}\"]`);\n}\n\n/**\n * Returns the `<input>` inside a field. Works for INPUT, DATEPICKER, and other fields\n * that render a single native input.\n */\nexport function getInput(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('input');\n}\n\n/**\n * Returns the validation error paragraph for a field.\n *\n * Targets the inner `<p class=\"tft-control-error\">` rather than the host element to\n * avoid Playwright strict-mode failures on fields like autocomplete/chiplist that\n * render two `tft-control-error` host elements (one for each internal input).\n *\n * @param fieldType - The kebab-case field type used in the component selector,\n * e.g. `'input'`, `'select'`, `'autocomplete'`, `'autocomplete-chiplist'`,\n * `'checkbox'`, `'datepicker'`, `'textarea'`, `'slider'`. Defaults to `'input'`.\n */\nexport function getError(page: Page, testId: string, fieldType = 'input'): Locator {\n return page.locator(`crispr-${fieldType}-field:has([data-testid=\"${testId}\"]) p.tft-control-error`);\n}\n\n/**\n * Returns the `<mat-label>` element inside a field's form field.\n */\nexport function getLabel(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('mat-label');\n}\n\n/**\n * Returns the `<mat-hint>` element inside a field's form field.\n */\nexport function getHint(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('mat-hint');\n}\n\n/**\n * Clicks an input and presses Tab to trigger a real blur event.\n * Angular's touched state is driven by blur, not just focus-out.\n */\nexport async function touchInput(page: Page, testId: string): Promise<void> {\n await getInput(page, testId).click();\n await page.keyboard.press('Tab');\n}\n\n/** Returns the `<mat-select>` element inside a select field. */\nexport function getMatSelect(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('mat-select');\n}\n\n/** Opens a `mat-select` dropdown. */\nexport async function openSelect(page: Page, testId: string): Promise<void> {\n await getMatSelect(page, testId).click();\n}\n\n/** Opens a `mat-select`, clicks the option with the given label, and waits for it to close. */\nexport async function selectOption(page: Page, testId: string, optionLabel: string): Promise<void> {\n await openSelect(page, testId);\n await page.locator('mat-option').filter({ hasText: optionLabel }).click();\n}\n\n/**\n * Opens a `mat-select`, presses Escape, then Tab to blur it.\n * The extra Tab is required — Escape alone dismisses the panel but does not blur\n * the trigger element, so `ControlErrorsDirective` never sees a blur event.\n */\nexport async function touchSelect(page: Page, testId: string): Promise<void> {\n await openSelect(page, testId);\n await page.keyboard.press('Escape');\n await page.keyboard.press('Tab');\n}\n\n/** Returns the `<mat-checkbox>` element for a checkbox field. */\nexport function getCheckbox(page: Page, testId: string): Locator {\n return page.locator(`[data-testid=\"${testId}\"]`);\n}\n\n/**\n * Clicks a checkbox twice (check then uncheck) and presses Tab to blur,\n * leaving it unchecked and touched — useful for triggering `requiredTrue` errors.\n */\nexport async function touchCheckbox(page: Page, testId: string): Promise<void> {\n await getCheckbox(page, testId).click();\n await getCheckbox(page, testId).click();\n await page.keyboard.press('Tab');\n}\n\n/**\n * Returns the visible search input for an autocomplete field.\n * Note: this is the `role=\"textbox\"` input, NOT the hidden `[formControlName]` anchor.\n */\nexport function getAutocompleteInput(page: Page, testId: string): Locator {\n return getMatFormField(page, testId).locator('input[type=\"textbox\"]');\n}\n\n/** Clicks the autocomplete input and presses Tab to blur. */\nexport async function touchAutocomplete(page: Page, testId: string): Promise<void> {\n await getAutocompleteInput(page, testId).click();\n await page.keyboard.press('Tab');\n}\n\n/**\n * Programmatically clicks the hidden crispr-form submit button.\n *\n * This fires both the native `submit` event (required by `ControlErrorsFormDirective`\n * to show errors on untouched controls) and Angular's `ngSubmit` event.\n *\n * Must use `evaluate` + native `.click()` because `display:none` elements\n * have no layout position for Playwright pointer events.\n *\n * @param nth - Zero-based index of the form on the page. Defaults to `0`.\n */\nexport async function submitForm(page: Page, nth = 0): Promise<void> {\n await page.evaluate((n) => {\n const triggers = document.querySelectorAll<HTMLButtonElement>('[data-testid=\"submit-trigger\"]');\n triggers[n]?.click();\n }, nth);\n}\n\n/** Clicks the datepicker input and presses Tab to blur. */\nexport async function touchDatepicker(page: Page, testId: string): Promise<void> {\n await getMatFormField(page, testId).locator('input').click();\n await page.keyboard.press('Tab');\n}\n"]}
package/index.js CHANGED
@@ -1,18 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
1
17
  // Load Angular's JIT compiler. Required because crispr-forms uses partial compilation
2
18
  // (Ivy linker format) which needs the JIT compiler as a fallback in Node/Playwright environments.
3
- import '@angular/compiler';
19
+ require("@angular/compiler");
4
20
  // Re-export Playwright so consumers only need one import.
5
- export * from '@playwright/test';
6
- export * from './helpers/form.helpers';
7
- export * from './field-tests/input.tests';
8
- export * from './field-tests/textarea.tests';
9
- export * from './field-tests/checkbox.tests';
10
- export * from './field-tests/select.tests';
11
- export * from './field-tests/slider.tests';
12
- export * from './field-tests/datepicker.tests';
13
- export * from './field-tests/autocomplete.tests';
14
- export * from './field-tests/autocomplete-chiplist.tests';
15
- export * from './field-tests/file-upload.tests';
16
- export * from './field-tests/unit-conversion.tests';
17
- export * from './field-tests/field-test-factory'; // exports testField and testForm
21
+ __exportStar(require("@playwright/test"), exports);
22
+ __exportStar(require("./helpers/form.helpers"), exports);
23
+ __exportStar(require("./field-tests/input.tests"), exports);
24
+ __exportStar(require("./field-tests/textarea.tests"), exports);
25
+ __exportStar(require("./field-tests/checkbox.tests"), exports);
26
+ __exportStar(require("./field-tests/select.tests"), exports);
27
+ __exportStar(require("./field-tests/slider.tests"), exports);
28
+ __exportStar(require("./field-tests/datepicker.tests"), exports);
29
+ __exportStar(require("./field-tests/autocomplete.tests"), exports);
30
+ __exportStar(require("./field-tests/autocomplete-chiplist.tests"), exports);
31
+ __exportStar(require("./field-tests/file-upload.tests"), exports);
32
+ __exportStar(require("./field-tests/unit-conversion.tests"), exports);
33
+ __exportStar(require("./field-tests/field-test-factory"), exports); // exports testField and testForm
18
34
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/crispr-forms-testing/src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,kGAAkG;AAClG,OAAO,mBAAmB,CAAC;AAE3B,0DAA0D;AAC1D,cAAc,kBAAkB,CAAC;AAEjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC,CAAC,iCAAiC","sourcesContent":["// Load Angular's JIT compiler. Required because crispr-forms uses partial compilation\n// (Ivy linker format) which needs the JIT compiler as a fallback in Node/Playwright environments.\nimport '@angular/compiler';\n\n// Re-export Playwright so consumers only need one import.\nexport * from '@playwright/test';\n\nexport * from './helpers/form.helpers';\nexport * from './field-tests/input.tests';\nexport * from './field-tests/textarea.tests';\nexport * from './field-tests/checkbox.tests';\nexport * from './field-tests/select.tests';\nexport * from './field-tests/slider.tests';\nexport * from './field-tests/datepicker.tests';\nexport * from './field-tests/autocomplete.tests';\nexport * from './field-tests/autocomplete-chiplist.tests';\nexport * from './field-tests/file-upload.tests';\nexport * from './field-tests/unit-conversion.tests';\nexport * from './field-tests/field-test-factory'; // exports testField and testForm\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/crispr-forms-testing/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sFAAsF;AACtF,kGAAkG;AAClG,6BAA2B;AAE3B,0DAA0D;AAC1D,mDAAiC;AAEjC,yDAAuC;AACvC,4DAA0C;AAC1C,+DAA6C;AAC7C,+DAA6C;AAC7C,6DAA2C;AAC3C,6DAA2C;AAC3C,iEAA+C;AAC/C,mEAAiD;AACjD,4EAA0D;AAC1D,kEAAgD;AAChD,sEAAoD;AACpD,mEAAiD,CAAC,iCAAiC","sourcesContent":["// Load Angular's JIT compiler. Required because crispr-forms uses partial compilation\n// (Ivy linker format) which needs the JIT compiler as a fallback in Node/Playwright environments.\nimport '@angular/compiler';\n\n// Re-export Playwright so consumers only need one import.\nexport * from '@playwright/test';\n\nexport * from './helpers/form.helpers';\nexport * from './field-tests/input.tests';\nexport * from './field-tests/textarea.tests';\nexport * from './field-tests/checkbox.tests';\nexport * from './field-tests/select.tests';\nexport * from './field-tests/slider.tests';\nexport * from './field-tests/datepicker.tests';\nexport * from './field-tests/autocomplete.tests';\nexport * from './field-tests/autocomplete-chiplist.tests';\nexport * from './field-tests/file-upload.tests';\nexport * from './field-tests/unit-conversion.tests';\nexport * from './field-tests/field-test-factory'; // exports testField and testForm\n"]}
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@tft/crispr-forms-testing",
3
- "version": "21.0.13",
3
+ "version": "21.0.15",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/nayfin/tft.git",
7
+ "directory": "libs/crispr-forms-testing"
8
+ },
4
9
  "main": "index.js",
5
10
  "types": "index.d.ts",
6
11
  "exports": {