lib-e2e-cypress-for-dummys-ts 0.9.0 → 1.0.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.
@@ -1,3 +1,33 @@
1
+ // src/utils/code-format.utils.ts
2
+ function gcd(a, b) {
3
+ while (b) {
4
+ const t = b;
5
+ b = a % b;
6
+ a = t;
7
+ }
8
+ return a;
9
+ }
10
+ function escapeSingleQuotes(value) {
11
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
12
+ }
13
+ function escapeCssAttrValue(value) {
14
+ return value.replace(/"/g, '\\"');
15
+ }
16
+ function normalizeBlock(code, baseIndent) {
17
+ const lines = code.split("\n").map((l) => l.trimEnd());
18
+ const nonEmpty = lines.filter((l) => l.trim().length > 0);
19
+ if (!nonEmpty.length) return "";
20
+ const indents = nonEmpty.map((l) => l.length - l.trimStart().length);
21
+ const minIndent = Math.min(...indents);
22
+ const relIndents = [...new Set(indents.map((n) => n - minIndent).filter((n) => n > 0))];
23
+ const step = relIndents.length > 0 ? relIndents.reduce(gcd) : 2;
24
+ return lines.map((l) => {
25
+ if (!l.trim()) return "";
26
+ const level = Math.round((l.length - l.trimStart().length - minIndent) / step);
27
+ return baseIndent + " ".repeat(level) + l.trimStart();
28
+ }).join("\n");
29
+ }
30
+
1
31
  // src/utils/selector-quality.utils.ts
2
32
  var FORBIDDEN_ID_PREFIXES = [
3
33
  "cdk-",
@@ -26,11 +56,11 @@ function getSelectorQuality(el) {
26
56
  }
27
57
  function buildPickerSelector(el) {
28
58
  const dataCy = el.getAttribute("data-cy");
29
- if (dataCy) return `[data-cy="${dataCy}"]`;
59
+ if (dataCy) return `[data-cy="${escapeCssAttrValue(dataCy)}"]`;
30
60
  const dataTestid = el.getAttribute("data-testid");
31
- if (dataTestid) return `[data-testid="${dataTestid}"]`;
61
+ if (dataTestid) return `[data-testid="${escapeCssAttrValue(dataTestid)}"]`;
32
62
  const ariaLabel = el.getAttribute("aria-label");
33
- if (ariaLabel) return `[aria-label="${ariaLabel}"]`;
63
+ if (ariaLabel) return `[aria-label="${escapeCssAttrValue(ariaLabel)}"]`;
34
64
  const rawId = el.id;
35
65
  if (rawId && rawId.length < 25 && /^[a-zA-Z][\w-]*$/.test(rawId) && !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) && !/^\d+$/.test(rawId)) {
36
66
  return `#${rawId}`;
@@ -366,7 +396,7 @@ var SelectorPickerElement = class extends HTMLElement {
366
396
  confirm(index) {
367
397
  const row = this.rows[index];
368
398
  if (!row) return;
369
- const command = `cy.get('${row.selector}').click()`;
399
+ const command = `cy.get('${escapeSingleQuotes(row.selector)}').click()`;
370
400
  this.recording.appendCommand(command);
371
401
  this.dispatchEvent(new CustomEvent("selectorchosen", { detail: command, bubbles: true, composed: true }));
372
402
  this.closeSilently();
@@ -384,14 +414,17 @@ var SelectorPickerElement = class extends HTMLElement {
384
414
  this.remove();
385
415
  }
386
416
  };
387
- if (!customElements.get("selector-picker")) {
388
- customElements.define("selector-picker", SelectorPickerElement);
417
+ if (!customElements.get("lib-e2e-selector-picker")) {
418
+ customElements.define("lib-e2e-selector-picker", SelectorPickerElement);
389
419
  }
390
420
 
391
421
  export {
422
+ escapeSingleQuotes,
423
+ escapeCssAttrValue,
424
+ normalizeBlock,
392
425
  FORBIDDEN_ID_PREFIXES,
393
426
  escHtml,
394
427
  escAttr,
395
428
  SelectorPickerElement
396
429
  };
397
- //# sourceMappingURL=chunk-CQEDHL7A.js.map
430
+ //# sourceMappingURL=chunk-24WFAT4W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/code-format.utils.ts","../src/utils/selector-quality.utils.ts","../src/components/selector-picker/selector-picker.styles.ts","../src/utils/html.utils.ts","../src/components/selector-picker/selector-picker.template.ts","../src/components/selector-picker/selector-picker.ts"],"sourcesContent":["function gcd(a: number, b: number): number {\n while (b) { const t = b; b = a % b; a = t; }\n return a;\n}\n\n/**\n * Escapes backslashes and single quotes so a value can be safely embedded inside\n * a single-quoted JavaScript string literal — e.g. an `it('…')` / `describe('…')`\n * name. Without this, a test named `User's login` produces broken generated JS.\n */\nexport function escapeSingleQuotes(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Escapes double quotes so a value can be safely embedded inside a CSS\n * double-quoted attribute selector, e.g. [data-cy=\"VALUE\"].\n * The result must subsequently pass through escapeSingleQuotes when it is\n * placed inside a single-quoted JS string literal (the JS layer doubles the\n * backslash introduced here).\n */\nexport function escapeCssAttrValue(value: string): string {\n return value.replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Normalizes indentation in a code block and prefixes every line with baseIndent.\n *\n * Algorithm:\n * 1. Strip trailing whitespace from each line.\n * 2. Find the minimum leading-whitespace count of non-empty lines (dedent).\n * 3. Compute the indent step as the GCD of all non-zero relative indent values,\n * so the original indent unit (4-space, 8-space, etc.) maps to 2-space levels.\n * 4. Re-emit each line as: baseIndent + ' '.repeat(level) + trimmedContent.\n *\n * This handles multi-line interceptor/command blocks that were stored with\n * inconsistent or file-origin indentation.\n */\nexport function normalizeBlock(code: string, baseIndent: string): string {\n const lines = code.split('\\n').map(l => l.trimEnd());\n const nonEmpty = lines.filter(l => l.trim().length > 0);\n if (!nonEmpty.length) return '';\n\n const indents = nonEmpty.map(l => l.length - l.trimStart().length);\n const minIndent = Math.min(...indents);\n const relIndents = [...new Set(indents.map(n => n - minIndent).filter(n => n > 0))];\n const step = relIndents.length > 0 ? relIndents.reduce(gcd) : 2;\n\n return lines\n .map(l => {\n if (!l.trim()) return '';\n const level = Math.round((l.length - l.trimStart().length - minIndent) / step);\n return baseIndent + ' '.repeat(level) + l.trimStart();\n })\n .join('\\n');\n}\n","import { escapeCssAttrValue } from './code-format.utils';\n\nexport type SelectorQuality = 'excellent' | 'good' | 'acceptable' | 'poor';\n\nexport const FORBIDDEN_ID_PREFIXES = [\n 'cdk-', 'mat-', 'p-', 'ng-', 'mdc-',\n 'primeng-', 'auto-', 'field-', 'input-', 'select-',\n];\n\nexport function getSelectorQuality(el: HTMLElement): SelectorQuality {\n if (\n el.hasAttribute('data-cy') ||\n el.hasAttribute('data-testid') ||\n el.hasAttribute('aria-label')\n ) {\n return 'excellent';\n }\n\n const rawId = el.id;\n if (\n rawId &&\n rawId.length < 25 &&\n /^[a-zA-Z][\\w-]*$/.test(rawId) &&\n !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) &&\n !/^\\d+$/.test(rawId)\n ) {\n return 'good';\n }\n\n if (typeof el.className === 'string' && el.className.trim().length > 0) {\n return 'acceptable';\n }\n\n return 'poor';\n}\n\n/** Returns the best cy.get() selector string for a given element. */\nexport function buildPickerSelector(el: HTMLElement): string {\n const dataCy = el.getAttribute('data-cy');\n if (dataCy) return `[data-cy=\"${escapeCssAttrValue(dataCy)}\"]`;\n\n const dataTestid = el.getAttribute('data-testid');\n if (dataTestid) return `[data-testid=\"${escapeCssAttrValue(dataTestid)}\"]`;\n\n const ariaLabel = el.getAttribute('aria-label');\n if (ariaLabel) return `[aria-label=\"${escapeCssAttrValue(ariaLabel)}\"]`;\n\n const rawId = el.id;\n if (\n rawId &&\n rawId.length < 25 &&\n /^[a-zA-Z][\\w-]*$/.test(rawId) &&\n !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) &&\n !/^\\d+$/.test(rawId)\n ) {\n return `#${rawId}`;\n }\n\n if (typeof el.className === 'string' && el.className.trim().length > 0) {\n const classes = el.className.trim().split(/\\s+/);\n return classes.map((c) => `.${c}`).join('');\n }\n\n return el.tagName.toLowerCase();\n}\n\n/** Human-readable key attribute/selector preview for a picker row (raw, unescaped). */\nexport function keyAttrDisplay(el: HTMLElement): string {\n for (const attr of ['data-cy', 'data-testid', 'aria-label']) {\n const v = el.getAttribute(attr);\n if (v) return `${attr}=\"${v}\"`;\n }\n if (el.id) return `id=\"${el.id}\"`;\n if (el.className && el.className.trim()) {\n return el.className.trim().split(/\\s+/).map((c) => `.${c}`).join('');\n }\n return '';\n}\n\n/** Plain, serializable view-model for one picker row — no DOM held. */\nexport interface PickerRow {\n quality: SelectorQuality;\n selector: string;\n tag: string;\n attr: string;\n}\n\n/** Reads an element once and returns the plain data a picker row needs to render. */\nexport function describePickerRow(el: HTMLElement): PickerRow {\n return {\n quality: getSelectorQuality(el),\n selector: buildPickerSelector(el),\n tag: el.tagName.toLowerCase(),\n attr: keyAttrDisplay(el),\n };\n}\n","export const SELECTOR_PICKER_STYLES = `\n :host {\n position: fixed;\n z-index: 2147483647;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n }\n\n .overlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n pointer-events: all;\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 10px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.6);\n min-width: 420px;\n max-width: 600px;\n font-family: 'Segoe UI', system-ui, sans-serif;\n color: #e6edf3;\n font-size: 13px;\n }\n\n .header {\n padding: 12px 16px 8px;\n border-bottom: 1px solid #21262d;\n font-weight: 600;\n font-size: 13px;\n color: #8b949e;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n }\n\n .list {\n max-height: 320px;\n overflow-y: auto;\n padding: 6px 0;\n }\n\n .row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 7px 14px;\n cursor: pointer;\n border-radius: 6px;\n margin: 1px 6px;\n transition: background 0.1s;\n }\n\n .row:hover,\n .row.selected {\n background: #21262d;\n }\n\n .row.selected {\n outline: 2px solid #388bfd;\n outline-offset: -2px;\n }\n\n .quality-badge {\n width: 18px;\n height: 18px;\n border-radius: 50%;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n }\n\n .badge-excellent { background: #238636; }\n .badge-good { background: #1f6feb; }\n .badge-acceptable{ background: #9e6a03; }\n .badge-poor { background: #da3633; }\n\n .tag-name {\n font-family: monospace;\n font-size: 12px;\n color: #8b949e;\n flex-shrink: 0;\n }\n\n .attr-value {\n font-family: monospace;\n font-size: 12px;\n color: #c9d1d9;\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .selector-preview {\n font-family: monospace;\n font-size: 11px;\n color: #58a6ff;\n flex-shrink: 0;\n max-width: 180px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .poor-warning {\n font-size: 10px;\n color: #f85149;\n margin-left: auto;\n }\n\n .footer {\n padding: 8px 14px 10px;\n border-top: 1px solid #21262d;\n display: flex;\n gap: 16px;\n font-size: 11px;\n color: #484f58;\n }\n\n .hint kbd {\n background: #21262d;\n border: 1px solid #30363d;\n border-radius: 3px;\n padding: 1px 5px;\n font-size: 10px;\n color: #8b949e;\n }\n`;\n","export function escHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\nexport function escAttr(s: string): string {\n return s.replace(/\"/g, '&quot;').replace(/</g, '&lt;');\n}\n","import type { PickerRow, SelectorQuality } from '../../utils/selector-quality.utils';\nimport { escHtml } from '../../utils/html.utils';\n\nconst QUALITY_EMOJI: Record<SelectorQuality, string> = {\n excellent: '🟢',\n good: '🔵',\n acceptable: '🟡',\n poor: '🔴',\n};\n\nconst QUALITY_CLASS: Record<SelectorQuality, string> = {\n excellent: 'badge-excellent',\n good: 'badge-good',\n acceptable: 'badge-acceptable',\n poor: 'badge-poor',\n};\n\nexport function renderPickerRows(\n rows: PickerRow[],\n selectedIndex: number,\n t: (key: string) => string,\n): string {\n return rows.map((row, i) => {\n const isSelected = i === selectedIndex;\n const isPoor = row.quality === 'poor';\n\n return `\n <div class=\"row${isSelected ? ' selected' : ''}\" data-idx=\"${i}\" role=\"option\" aria-selected=\"${isSelected}\">\n <span class=\"quality-badge ${QUALITY_CLASS[row.quality]}\" title=\"${escHtml(t(`SELECTOR_PICKER.QUALITY_${row.quality.toUpperCase()}`))}\">\n ${QUALITY_EMOJI[row.quality]}\n </span>\n <span class=\"tag-name\">&lt;${escHtml(row.tag)}&gt;</span>\n ${row.attr ? `<span class=\"attr-value\">${escHtml(row.attr)}</span>` : '<span class=\"attr-value\"></span>'}\n <span class=\"selector-preview\">${escHtml(row.selector)}</span>\n ${isPoor ? `<span class=\"poor-warning\" title=\"${escHtml(t('SELECTOR_PICKER.QUALITY_POOR'))}\">⚠</span>` : ''}\n </div>`;\n }).join('');\n}\n\nexport function renderPicker(\n rows: PickerRow[],\n selectedIndex: number,\n t: (key: string) => string,\n): string {\n return `\n <div class=\"overlay\" role=\"listbox\">\n <div class=\"header\">${escHtml(t('SELECTOR_PICKER.TITLE'))}</div>\n <div class=\"list\">\n ${renderPickerRows(rows, selectedIndex, t)}\n </div>\n <div class=\"footer\">\n <span class=\"hint\"><kbd>↑↓</kbd> ${escHtml(t('SELECTOR_PICKER.PREVIEW_LABEL'))}</span>\n <span class=\"hint\"><kbd>Enter</kbd> ${escHtml(t('SELECTOR_PICKER.CONFIRM_HINT'))}</span>\n <span class=\"hint\"><kbd>Esc</kbd> ${escHtml(t('SELECTOR_PICKER.CANCEL_HINT'))}</span>\n </div>\n </div>`;\n}\n","import type { RecordingService } from '../../services/recording.service';\nimport type { TranslationService } from '../../services/translation.service';\nimport { describePickerRow, type PickerRow } from '../../utils/selector-quality.utils';\nimport { escapeSingleQuotes } from '../../utils/code-format.utils';\nimport { SELECTOR_PICKER_STYLES } from './selector-picker.styles';\nimport { renderPicker } from './selector-picker.template';\n\nconst OWN_DATA_CY = 'lib-e2e-cypress-for-dummys';\nconst MAX_ANCESTORS = 10;\n\nexport class SelectorPickerElement extends HTMLElement {\n targetElement: HTMLElement | null = null;\n recording!: RecordingService;\n translation!: TranslationService;\n\n private shadow: ShadowRoot;\n private ancestors: HTMLElement[] = [];\n private rows: PickerRow[] = [];\n private selectedIndex = 0;\n private keyHandler: ((e: KeyboardEvent) => void) | null = null;\n private unsubRecording: (() => void) | null = null;\n private unsubPause: (() => void) | null = null;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void {\n this.setAttribute('data-cy', 'lib-e2e-cypress-for-dummys');\n this.ancestors = this.buildAncestors();\n this.rows = this.ancestors.map(describePickerRow);\n this.selectedIndex = this.findBestIndex();\n this.render();\n this.attachKeyListener();\n this.attachRowClickListeners();\n this.subscribeToRecordingChanges();\n }\n\n disconnectedCallback(): void {\n this.detachKeyListener();\n this.unsubRecording?.();\n this.unsubPause?.();\n }\n\n private t(key: string): string {\n return this.translation?.translate(key) ?? key;\n }\n\n // ── Ancestor chain ──────────────────────────────────────────────────────────\n\n private buildAncestors(): HTMLElement[] {\n const chain: HTMLElement[] = [];\n let current: HTMLElement | null = this.targetElement;\n\n while (current && current.tagName.toLowerCase() !== 'html' && chain.length < MAX_ANCESTORS) {\n if (current.getAttribute('data-cy') === OWN_DATA_CY) {\n current = current.parentElement;\n continue;\n }\n chain.push(current);\n current = current.parentElement;\n }\n\n return chain;\n }\n\n private findBestIndex(): number {\n for (let i = 0; i < this.rows.length; i++) {\n const q = this.rows[i].quality;\n if (q === 'excellent' || q === 'good' || q === 'acceptable') return i;\n }\n return 0;\n }\n\n // ── Rendering ───────────────────────────────────────────────────────────────\n\n private render(): void {\n this.shadow.innerHTML = `<style>${SELECTOR_PICKER_STYLES}</style>${renderPicker(\n this.rows,\n this.selectedIndex,\n this.t.bind(this),\n )}`;\n }\n\n // ── Keyboard ────────────────────────────────────────────────────────────────\n\n private attachKeyListener(): void {\n this.keyHandler = (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown') {\n e.stopPropagation();\n e.preventDefault();\n this.selectedIndex = (this.selectedIndex + 1) % this.ancestors.length;\n this.render();\n this.attachRowClickListeners();\n } else if (e.key === 'ArrowUp') {\n e.stopPropagation();\n e.preventDefault();\n this.selectedIndex = (this.selectedIndex - 1 + this.ancestors.length) % this.ancestors.length;\n this.render();\n this.attachRowClickListeners();\n } else if (e.key === 'Enter') {\n e.stopPropagation();\n this.confirm(this.selectedIndex);\n } else if (e.key === 'Escape') {\n e.stopPropagation();\n this.cancel();\n }\n };\n window.addEventListener('keydown', this.keyHandler, { capture: true });\n }\n\n private detachKeyListener(): void {\n if (this.keyHandler) {\n window.removeEventListener('keydown', this.keyHandler, { capture: true });\n this.keyHandler = null;\n }\n }\n\n // ── Row click listeners ─────────────────────────────────────────────────────\n\n private attachRowClickListeners(): void {\n this.shadow.querySelectorAll('[data-idx]').forEach((row) => {\n (row as HTMLElement).addEventListener('click', () => {\n const idx = parseInt((row as HTMLElement).dataset['idx'] ?? '0', 10);\n this.confirm(idx);\n });\n });\n }\n\n // ── Recording auto-close ────────────────────────────────────────────────────\n\n private subscribeToRecordingChanges(): void {\n this.unsubRecording = this.recording.onRecordingChange((isRecording) => {\n if (!isRecording) this.closeSilently();\n });\n this.unsubPause = this.recording.onPauseChange((isPaused) => {\n if (isPaused) this.closeSilently();\n });\n }\n\n // ── Actions ─────────────────────────────────────────────────────────────────\n\n private confirm(index: number): void {\n const row = this.rows[index];\n if (!row) return;\n const command = `cy.get('${escapeSingleQuotes(row.selector)}').click()`;\n this.recording.appendCommand(command);\n this.dispatchEvent(new CustomEvent('selectorchosen', { detail: command, bubbles: true, composed: true }));\n this.closeSilently();\n }\n\n private cancel(): void {\n this.dispatchEvent(new CustomEvent('pickercancelled', { bubbles: true, composed: true }));\n this.closeSilently();\n }\n\n private closeSilently(): void {\n this.detachKeyListener();\n this.unsubRecording?.();\n this.unsubPause?.();\n this.unsubRecording = null;\n this.unsubPause = null;\n this.remove();\n }\n}\n\nif (!customElements.get('lib-e2e-selector-picker')) {\n customElements.define('lib-e2e-selector-picker', SelectorPickerElement);\n}\n"],"mappings":"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","names":[]}