@cypress/unique-selector

中文文档
2.2.0发布于 2026/03/27MITCommonJS近 30 天下载 1.2万

鉴于 DOM 节点, 返回只匹配该元素的独有 CSS 选择器

中文使用文档
文档目录12 节
  1. 安装
  2. API 密码
  3. unique(element, options)
  4. 用法实例
  5. 基本用途
  6. 自定义选择器类型
  7. 过滤选择器
  8. 必需属性
  9. 用缓存优化性能
  10. 阴影 DOM 支持
  11. 选择生成策略
  12. 生成选择器实例

独选者

鉴于 DOM 节点, 返回唯一匹配该元素的 CSS 选择器 .

选择器的独特性根据给定元素的根节点来确定. 在Shadow DOM中渲染出元素,将在关联的ShadowRoot上下文中得出一个独有的选择器. 否则,将产生元素自有文档中独有的选择器.

安装

NPM Version

npm install @cypress/unique-selector

API 密码

unique(element, options)

为指定的 DOM 元素生成一个独特的 CSS 选择器.

参数

  • element (Element) - 用于生成唯一选择器的 DOM 元素
  • options (对象,可选) - 选择器生成的配置选项

选项

  • selectorTypes (String [],可选) - 按偏好顺序排列选择器类型。 默认 : ['id', 'name', 'class', 'tag', 'nth-child']

    可用的选择器类型 :

    • 'id' - 使用元素的ID属性(例如, #myId(中文(简体) )
    • 'name' - 使用元素的名称属性(例如, [name="myName"](中文(简体) )
    • 'class' - 使用元素的类属性(例如, .myClass(中文(简体) )
    • 'tag' - 使用元素的标记名称(例如, div, (中文(简体) ), span(中文(简体) )
    • 'nth-child' - 使用非孩子位置(例如:, :nth-child(1)(中文(简体) )
    • 'attributes' - 使用所有属性,但不包括: attributesToIgnore
    • 'data-*' - 使用特定数据属性(例如, data-foo, (中文(简体) ), data-test-id(中文(简体) )
    • 'attribute:*' - 使用特定属性(例如, attribute:role, (中文(简体) ), attribute:aria-label(中文(简体) )
  • attributesToIgnore (String [],可选) - 生成选择器时要忽略的属性名称的组合. 默认 : ['id', 'class', 'length']

  • filter (功能,可选) - 在构建选择器时有条件拒绝各种特性的过滤功能.

    function filter(type, key, value) {
      // type: 'attribute', 'class', 'tag', 'nth-child'
      // key: attribute name (for attributes), class name (for classes), etc.
      // value: attribute value, class name, tag name, nth-child position
      
      // Return true to allow this trait, false to reject it
      return true;
    }
    
  • selectorCache (map<Element, String>,可选) - 缓存可以提高重复选择器生成的性能. 呼叫者负责缓存无效.

  • isUniqueCache (map<String, Boolean>,可选) - 缓存可以提高重复的独特性检查的性能. 呼叫者负责缓存无效.

  • requiredAttributes (Object,可选) - 指定必须出现在生成的选取器中的属性,无论这些属性是否需要独有性. 当提供时,匹配的属性选择器会被编织入每个元素的片段 > 链,而独有链上方的祖先则使用后人梳理器进行预作.

    此选项优先于 selectorTypes 财务报告和审定财务报表 filter 对于它所命名的属性——如果一个元素具有需要的属性,则其属性 [attr="value"] 即使 filter 为了独特性的目的拒绝该属性,即使该属性未列入 selectorTypes。 。 。 .

    这个 requiredAttributes 对象的形状如下:

    • attributeNames (String[]) - 向选择器注入的属性名(例如, ['data-component', 'data-cy']) (中文(简体) ). 精确的属性名称只——而不是图案或正则名. 名称在生成的选取器中按规定使用,没有内部正常化,因此您提供的外壳是输出中出现的外壳. 当属性在 attributeNames 已经存在于基准选择器中(来自 selectorTypes),去dup检测为对病例不敏感,所以无论病例差异如何,重复注射都会被正确压制.
    • filter (功能,可选) - 一个过滤功能,其签名与顶级相同 filter 选项,独立用于控制哪个属性 数值 允许注射。 返回时 false 以跳过给定元素的注入。 此过滤器与顶层分离 filter 并服务于不同的目的: filter 有资格建立 独一无二 选择器,同时 requiredAttributes.filter 属性值符合条件的控件 注射编辑 key 引用到此函数的参数将符合下列条件: attributeNames。 。 。 .
    • elementCache (map<Element, (string-|null) [] >,可选) - 每元素所需的属性选择器缓存 。 每个缓存项是单个选择器字符串的阵列,与 attributeNames (未显示或过滤出属性的空白). 呼叫者负责缓存无效.
    unique(element, {
      requiredAttributes: {
        attributeNames: ['data-component', 'data-cy'],
        filter: (type, key, value) => {
          // Exclude auto-generated component names from injection
          if (type === 'attribute' && key === 'data-component') {
            return !value.startsWith('jss-');
          }
          return true;
        },
        elementCache: new Map(),
      }
    });
    

回返

  • 字符串 - 该元素的独有CSS选择器,或 null 如果无法生成唯一选择器

用法实例

基本用途

import unique from '@cypress/unique-selector';

// Get a unique selector for an element
const element = document.querySelector('.my-button');
const selector = unique(element);
// Returns: '#my-button' or '.my-button' or 'button' etc.

自定义选择器类型

// Use only ID and class selectors
const selector = unique(element, {
    selectorTypes: ['id', 'class']
});

// Use only data attributes
const selector = unique(element, {
    selectorTypes: ['data-test-id', 'data-cy']
});

// Use specific attributes
const selector = unique(element, {
    selectorTypes: ['attribute:role', 'attribute:aria-label']
});

过滤选择器

// Filter out certain IDs
const selector = unique(element, {
    filter: (type, key, value) => {
        if (type === 'attribute' && key === 'id') {
            // Only allow IDs that contain 'test'
            return value.includes('test');
        }
        return true;
    }
});

// Filter out certain classes
const selector = unique(element, {
    filter: (type, key, value) => {
        if (type === 'class') {
            // Only allow classes that start with 'btn-'
            return value.startsWith('btn-');
        }
        return true;
    }
});

必需属性

使用 requiredAttributes 当您想要特定属性总是出现在生成的选择器中时,无论这些属性是否有助于独有性。 当应用程序使用语义元件属性(如:, data-component, (中文(简体) ), data-cy您想要在每个选择器中反映可读性或稳定性.

// Always include data-component in the selector, even when an ID alone would be unique
const selector = unique(element, {
    requiredAttributes: {
        attributeNames: ['data-component']
    }
});
// '#submit-button' becomes '#submit-button[data-component="PrimaryButton"]'
// Ancestors with data-component are prepended with descendant combinators:
// '[data-component="Form"] #submit-button[data-component="PrimaryButton"]'

所需属性优先于 selectorTypes 财务报告和审定财务报表 filter。如果元素具有要求的属性,则将注入选择器,即使:

  • 属性未在 selectorTypes
  • 高层 filter 为了独特性而拒绝这种属性
// The top-level filter rejects data-component for uniqueness building,
// but requiredAttributes.filter allows it to still be injected.
const selector = unique(element, {
    filter: (type, key) => key !== 'data-component',
    requiredAttributes: {
        attributeNames: ['data-component'],
        // No requiredAttributes.filter — all values are injected
    }
});
// data-component still appears in the output

使用 requiredAttributes.filter 独立控制哪个属性 数值 注射,但不影响确定独特性的方式:

// Inject data-component only when the value doesn't look auto-generated
const selector = unique(element, {
    requiredAttributes: {
        attributeNames: ['data-component'],
        filter: (type, key, value) => {
            if (type === 'attribute' && key === 'data-component') {
                return !value.startsWith('jss-');
            }
            return true;
        },
        elementCache: new Map(), // reuse across calls for performance
    }
});

当多个 attributeNames 指定,每个元素独立匹配:

const selector = unique(element, {
    requiredAttributes: {
        attributeNames: ['data-cy', 'data-region']
    }
});
// '[data-region="main"] [data-cy="dashboard"] .widget[data-cy="widget-a"]'

用缓存优化性能

const selectorCache = new Map();
const isUniqueCache = new Map();

const selector = unique(element, {
    selectorCache,
    isUniqueCache
});

// Reuse the same caches for multiple calls
const selector2 = unique(anotherElement, {
    selectorCache,
    isUniqueCache
});

阴影 DOM 支持

// Works with Shadow DOM elements
const shadowHost = document.querySelector('#shadow-host');
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
const shadowElement = shadowRoot.querySelector('.shadow-button');

const selector = unique(shadowElement);
// Returns a selector unique within the shadow root context

选择生成策略

库遵循这个策略生成独特的选择器 :

  1. 元素级独有性: 首先尝试找到一个在母体中唯一识别元素的筛选器
  2. 双向: 如果元素级独有性失败, 则会穿过 DOM 树, 建立选择器路径
  3. 选择者类型优先: 使用 selectorTypes 数组以决定要先尝试的选定者类型
  4. 组合后退: 对于类和属性,如果单个选择者不独有,请尝试多个选择者的组合
  5. Nth- child倒计时: 将非儿童定位作为最后手段
  6. 必需属性注射: 独一无二之后 > 链被确定,任何 requiredAttributes 被编织入每个元素的链段。 在链上方带有所需要属性的祖先被准备为后人梳理. 必要的属性即使因独特性而不需要,甚至顶层也会被注入 filter 将这些人排除在考虑之外.

生成选择器实例

<!-- Element with ID -->
<div id="header">Header</div>
<!-- Selector: #header -->

<!-- Element with unique class -->
<button class="submit-btn">Submit</button>
<!-- Selector: .submit-btn -->

<!-- Element with multiple classes -->
<div class="card primary large">Card</div>
<!-- Selector: .card.primary.large -->

<!-- Element with data attributes -->
<div data-test-id="user-profile">Profile</div>
<!-- Selector: [data-test-id="user-profile"] -->

<!-- Element with custom attributes -->
<button role="button" aria-label="Close">×</button>
<!-- Selector: [role="button"] or [aria-label="Close"] -->

<!-- Element requiring nth-child -->
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<!-- Selector: :nth-child(1) or :nth-child(2) -->

<!-- Complex nested element -->
<div class="container">
  <div class="wrapper">
    <span class="text">Hello</span>
  </div>
</div>
<!-- Selector: .container > .wrapper > .text -->

版本与发布记录

@cypress/unique-selector 共发布 17 个版本,首次发布于 2017/12/14;过去 12 个月发布了 3 个版本。

版本发布日期距今
2.2.0latest2026/03/277 个月前
2.1.32026/01/239 个月前
2.1.22026/01/229 个月前
2.1.12025/05/201.5 年前
2.1.02025/04/041.6 年前
2.0.12024/08/052 年前

关于 @cypress/unique-selector 的常见问题

@cypress/unique-selector 是什么?

鉴于 DOM 节点, 返回只匹配该元素的独有 CSS 选择器

如何安装 @cypress/unique-selector?

在项目目录运行 npm install @cypress/unique-selector,或使用 pnpm add / yarn add / bun add。

@cypress/unique-selector 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/cypress__unique-selector 是否存在。

@cypress/unique-selector 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@cypress/unique-selector 可以商用吗?

@cypress/unique-selector 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cypress/unique-selector 的下载量有多少?

根据 npm 官方下载统计,@cypress/unique-selector 在 2026/10/11 – 2026/11/09 这 30 天内被下载 12,036 次,日均约 401 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cypress/unique-selector 还在维护吗?

最新版本 2.2.0 发布于 2026/03/27(7 个月前);至今共发布 17 个版本,其中过去 12 个月发布了 3 个;首次发布于 2017/12/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。