For AI agents: the complete documentation index is available at https://rstest.rs/zh/llms.txt, the full documentation bundle is available at https://rstest.rs/zh/llms-full.txt, and this page is available as Markdown at https://rstest.rs/zh/api/runtime-api/browser-mode/locator.md.
close
  • 简体中文
  • Locator

    Locator 是 Browser Mode 的元素查询与交互核心 API。你可以通过 page.getBy* 或 page.locator() 构建查询链,再执行交互操作。具体执行语义由 browser provider 决定。

    自动等待

    使用 Playwright provider 时,Locator 交互方法(如 click、fill、check)会自动等待元素进入可操作状态(可见、启用、稳定)后再执行,你不需要在操作前手动等待元素。这与 expect.element 断言的自动重试机制不同。

    下面的示例展示了典型工作流:查询元素、执行交互,并配合 expect.element 进行断言。

    src/locator.test.ts
    import { page } from '@rstest/browser';
    import { expect, test } from '@rstest/core';
    
    test('interacts with a form using locator', async () => {
      await page.getByLabel('Username').fill('alice');
      await page.getByLabel('Password').fill('secret123');
      await page.getByRole('button', { name: 'Login' }).click();
    
      await expect.element(page.getByLabel('Username')).toHaveValue('alice');
    });

    page

    • 类型: BrowserPage

    page 是测试里的起点:先用 page 定位元素,再在返回的 Locator 上执行交互和断言。

    通过查询方法创建 Locator。要向当前焦点发送键盘输入,请使用 page.keyboard。

    const submitButton = page.getByRole('button', { name: 'Submit' });

    上面的 submitButton 是一个 Locator,后续可以继续链式调用(例如 .click())或传给 expect.element(...) 做断言。

    BrowserPage

    • 类型: Pick<Locator, 'locator' | 'getByRole' | 'getByText' | 'getByLabel' | 'getByPlaceholder' | 'getByAltText' | 'getByTitle' | 'getByTestId'> & { elementLocator: (element: Element) => Locator; keyboard: BrowserKeyboard }

    BrowserPage 是 page 的类型定义,提供查询入口、DOM 到 Locator 的转换,以及类型为 BrowserKeyboard 的 keyboard。click、fill 等元素交互方法由 Locator 提供。

    也就是说,你需要先通过 page 拿到 Locator,再在 Locator 上调用交互和断言。

    查询 API

    以下 API 都会返回新的 Locator,可继续链式调用。

    locator

    • 类型: (selector: string) => Locator

    通过 CSS selector 查询元素。

    const item = page.locator('.todo-item');

    getByRole

    • 类型: (role: string, options?: LocatorGetByRoleOptions) => Locator

    按语义角色查询元素,推荐优先使用。

    LocatorGetByRoleOptions 支持:name、exact、checked、disabled、expanded、selected、pressed、includeHidden、level。

    const saveBtn = page.getByRole('button', { name: 'Save' });

    getByText

    • 类型: (text: string | RegExp, options?: { exact?: boolean }) => Locator

    按可见文本查询。

    const successMessage = page.getByText('Saved successfully');

    getByLabel

    • 类型: (text: string | RegExp, options?: { exact?: boolean }) => Locator

    按表单 label 查询。

    const emailInput = page.getByLabel('Email');

    getByPlaceholder

    • 类型: (text: string | RegExp, options?: { exact?: boolean }) => Locator

    按 placeholder 查询。

    const searchInput = page.getByPlaceholder('Search');

    getByAltText

    • 类型: (text: string | RegExp, options?: { exact?: boolean }) => Locator

    按 alt 文本查询。

    const avatarImage = page.getByAltText('User avatar');

    getByTitle

    • 类型: (text: string | RegExp, options?: { exact?: boolean }) => Locator

    按 title 查询。

    const helpIcon = page.getByTitle('Help');

    getByTestId

    • 类型: (text: string | RegExp) => Locator

    按 test id 查询。

    const settingsPanel = page.getByTestId('settings-panel');

    elementLocator

    • 类型: (element: Element) => Locator

    将当前测试文档中的 DOM Element 同步转换为 Locator。这样可以把 Testing Library 或第三方工具返回的元素用于真实浏览器操作和 Rstest 断言,支持 HTML、SVG 以及 shadow DOM 中的元素。

    import { getByRole } from '@testing-library/dom';
    
    const button = getByRole(document.body, 'button', { name: 'Save' });
    await page.elementLocator(button).click();
    await expect.element(button).toBeEnabled();

    Locator 始终指向原始元素,不会修改 DOM 属性。组件替换节点后,这个 Locator 仍指向旧节点:断言元素已卸载会通过,交互操作会等待原节点重新挂载或超时。如果需要在重渲染后重新查找元素,请使用 page.getByRole() 等查询 Locator。

    不接受其他文档或 iframe 中的元素。当前文档中尚未挂载的元素可以提前转换。

    配置 API

    setTestIdAttribute

    • 类型: (attribute: string) => Promise<void>

    设置 getByTestId() 使用的属性名。默认值是 data-testid。

    这个配置会通过 Browser Mode 通道转发到 host provider(例如 Playwright 的 selectors.setTestIdAttribute())。

    这是全局配置,建议在测试 setup 阶段统一设置一次,避免在用例执行中途修改导致查询行为不一致。

    import { page, setTestIdAttribute } from '@rstest/browser';
    
    await setTestIdAttribute('data-test');
    await page.getByTestId('settings-panel').click();
    Tip

    建议在 setup 文件中配置 setTestIdAttribute,确保所有测试统一生效:

    rstest.setup.ts
    import { setTestIdAttribute } from '@rstest/browser';
    
    await setTestIdAttribute('data-qa');

    然后在配置中引用:

    rstest.config.ts
    export default defineConfig({
      setupFiles: ['./rstest.setup.ts'],
    });

    组合 API

    filter

    • 类型: (options: LocatorFilterOptions) => Locator

    LocatorFilterOptions 支持:

    • hasText?: string | RegExp:保留文本匹配的元素
    • hasNotText?: string | RegExp:排除文本匹配的元素
    • has?: Locator:保留包含子 Locator 的元素
    • hasNot?: Locator:排除包含子 Locator 的元素

    用于在已有查询结果上做二次过滤。

    const profileSave = page
      .locator('section')
      .filter({ has: page.getByRole('heading', { name: 'Profile' }) })
      .getByRole('button', { name: 'Save' });
    const visibleItems = page.locator('li').filter({
      hasNotText: /archived/i,
      hasNot: page.getByRole('img', { name: 'Locked' }),
    });

    and / or

    • 类型: (other: Locator) => Locator

    合并两个 Locator 条件。

    const byRole = page.getByRole('button', { name: 'Submit' });
    const byId = page.locator('#submit');
    
    const exactOne = byRole.and(byId);

    nth / first / last

    • 类型:
      • nth(index: number): Locator
      • first(): Locator
      • last(): Locator

    在匹配集合中选择指定元素。

    交互 API

    以下 API 会触发实际浏览器操作,并返回 Promise<void>。

    严格模式

    Locator 是严格的。如果交互操作(如 click、fill)匹配到多个元素,会抛出错误。当查询匹配多个元素时,请使用 first()、last() 或 nth() 显式选择单个元素。

    这些 *Options 类型表示 Browser Mode 当前稳定支持的一组选项:

    • LocatorClickOptions / LocatorDblclickOptions: button、delay、force、modifiers、position、timeout、trial(click 额外支持 clickCount)
    • LocatorHoverOptions: force、modifiers、position、timeout、trial
    • LocatorDragToOptions: force、sourcePosition、targetPosition、timeout、trial
    • LocatorPressOptions: delay、timeout
    • LocatorFillOptions: force、timeout
    • LocatorCheckOptions: force、position、timeout、trial
    • LocatorFocusOptions / LocatorBlurOptions / LocatorScrollIntoViewIfNeededOptions: timeout
    • LocatorWaitForOptions: state(attached / detached / visible / hidden)与 timeout
    • LocatorSelectOptionOptions: force、timeout
    • LocatorSetInputFilesOptions: timeout

    click

    • 类型: (options?: LocatorClickOptions) => Promise<void>

    点击当前 Locator 匹配到的元素。

    await page.getByRole('button', { name: 'Submit' }).click();

    dblclick

    • 类型: (options?: LocatorDblclickOptions) => Promise<void>

    对元素执行双击操作。

    await page.getByText('Open details').dblclick();

    dragTo

    • 类型: (target: Locator, options?: LocatorDragToOptions) => Promise<void>

    将当前元素拖到目标 Locator。sourcePosition 和 targetPosition 分别相对于源元素和目标元素的左上角内边距边界。

    await page.getByTestId('card').dragTo(page.getByTestId('column'));

    hover

    • 类型: (options?: LocatorHoverOptions) => Promise<void>

    将鼠标悬停到元素上,常用于触发 hover 菜单或 tooltip。

    await page.getByRole('button', { name: 'More' }).hover();

    press

    • 类型: (key: string, options?: LocatorPressOptions) => Promise<void>

    在元素上发送键盘按键。

    await page.getByLabel('Search').press('Enter');

    pressSequentially

    • 类型: (text: string, options?: LocatorPressOptions) => Promise<void>

    逐个字符地向元素输入 text,并为每个字符发送一次键盘按键。适用于需要响应单个按键事件的元素,例如自动补全输入框或键盘快捷键;其他情况下优先使用 fill。delay 用于设置每次按键之间的等待时间(毫秒)。

    await page.getByLabel('Search').pressSequentially('rstest');

    fill

    • 类型: (value: string, options?: LocatorFillOptions) => Promise<void>

    设置输入框值,适用于 input、textarea 等可输入元素。

    await page.getByPlaceholder('Email').fill('dev@rstest.rs');

    clear

    • 类型: () => Promise<void>

    清空当前输入元素的值。

    await page.getByPlaceholder('Email').clear();

    focus

    • 类型: (options?: LocatorFocusOptions) => Promise<void>

    让元素获得焦点。

    await page.getByLabel('Username').focus();

    blur

    • 类型: (options?: LocatorBlurOptions) => Promise<void>

    让元素失去焦点。

    await page.getByLabel('Username').blur();

    check

    • 类型: (options?: LocatorCheckOptions) => Promise<void>

    勾选 checkbox 或 radio。

    await page.getByLabel('Agree').check();

    uncheck

    • 类型: (options?: LocatorCheckOptions) => Promise<void>

    取消勾选 checkbox。

    await page.getByLabel('Agree').uncheck();

    scrollIntoViewIfNeeded

    • 类型: (options?: LocatorScrollIntoViewIfNeededOptions) => Promise<void>

    必要时滚动页面,使元素进入可视区域。

    await page.getByRole('button', { name: 'Load more' }).scrollIntoViewIfNeeded();

    waitFor

    • 类型: (options?: LocatorWaitForOptions) => Promise<void>

    等待 Locator 满足条件后继续执行,适合处理异步渲染。

    await page.getByText('Ready').waitFor();

    dispatchEvent

    • 类型: (type: string, eventInit?: LocatorDispatchEventInit) => Promise<void>

    在元素上派发自定义事件或原生事件。

    await page.getByRole('button', { name: 'Event' }).dispatchEvent('custom');

    selectOption

    • 类型: (value: string | string[], options?: LocatorSelectOptionOptions) => Promise<void>

    选择 select 元素的 option。当前只支持 string 或 string[] 作为 value。

    await page.getByLabel('Choice').selectOption('b');

    setInputFiles

    • 类型: (files: string | string[], options?: LocatorSetInputFilesOptions) => Promise<void>

    为 input[type="file"] 设置文件。当前只支持文件路径 string 或 string[]。

    await page.locator('#upload').setInputFiles('/tmp/demo.txt');

    使用约束

    • 本页列出的 API 是当前支持的 Playwright Locator API 子集,未列出的 API 暂不可用
    • and / or / filter({ has | hasNot }) 的参数必须是 @rstest/browser 返回的 Locator
    • dispatchEvent(type, eventInit?) 的 type 必须是非空字符串
    • selectOption 目前仅支持 string 或 string[]
    • setInputFiles 目前仅支持文件路径 string 或 string[]
    • 部分参数会通过 Browser Mode 通信通道传输,建议保持可被 JSON 序列化

    与 expect.element 配合

    Locator 一般与 expect.element(locator) 配合使用。完整断言列表见 Assertion。