close
  • 简体中文
  • Locator

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

    自动等待

    使用 Playwright provider 时,Locator 交互方法(如 clickfillcheck)会自动等待元素进入可操作状态(可见、启用、稳定)后再执行,你不需要在操作前手动等待元素。这与 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 上执行交互和断言。

    page 是仅用于查询的对象:只负责创建 Locator,不直接执行交互动作。

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

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

    BrowserPage

    • 类型: Pick<Locator, 'locator' | 'getByRole' | 'getByText' | 'getByLabel' | 'getByPlaceholder' | 'getByAltText' | 'getByTitle' | 'getByTestId'>

    BrowserPagepage 的类型定义,只暴露查询入口,不包含 clickfill 等交互方法。

    也就是说,你需要先通过 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 支持:nameexactcheckeddisabledexpandedselectedpressedincludeHiddenlevel

    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');

    配置 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 是严格的。如果交互操作(如 clickfill)匹配到多个元素,会抛出错误。当查询匹配多个元素时,请使用 first()last()nth() 显式选择单个元素。

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

    • LocatorClickOptions / LocatorDblclickOptions: buttondelayforcemodifierspositiontimeouttrialclick 额外支持 clickCount
    • LocatorHoverOptions: forcemodifierspositiontimeouttrial
    • LocatorPressOptions: delaytimeout
    • LocatorFillOptions: forcetimeout
    • LocatorCheckOptions: forcepositiontimeouttrial
    • LocatorFocusOptions / LocatorBlurOptions / LocatorScrollIntoViewIfNeededOptions: timeout
    • LocatorWaitForOptions: stateattached / detached / visible / hidden)与 timeout
    • LocatorSelectOptionOptions: forcetimeout
    • 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();

    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');

    fill

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

    设置输入框值,适用于 inputtextarea 等可输入元素。

    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。当前只支持 stringstring[] 作为 value。

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

    setInputFiles

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

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

    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 目前仅支持 stringstring[]
    • setInputFiles 目前仅支持文件路径 stringstring[]
    • 部分参数会通过 Browser Mode 通信通道传输,建议保持可被 JSON 序列化

    与 expect.element 配合

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