playwright常用方法介绍

338 阅读3分钟

mock接口

使用场景

  • 比如有验证UI的展示,就可以通过mock接口返回值
  • 比如要验证某个操作失败的情况,就可以通过mock接口的返回状态

模拟返回值,比如有下面的接口,返回值格式

// 接口
fetch('https://mock.data.com/api/list')

// 返回值
{
  items: [
    { name: 'Tom', id: 1 },
    { name: 'Jerry', id: 2 },
    { name: 'Jonk', id: 3 },
  ],
  total: 199,
};

单个测试用例中mock

test('测试mock接口返回值', async ({ page }) => {
  await page.route('*/api/list', async (route) => {
    const response = await route.fetch();
    // json 就是返回的数据
    const json = await response.json();
    // 根据需要对数据进行处理
    json.items = json.items.map((it) => {
      if(it.id === 1) {
        return { ...it, hide: true}
      }
      return it
    })
    await route.fulfill({ response, json });
  });

  // todo...
  
  // 最后不要忘了将mock的接口解除
  await page.unroute('*/api/list');
});

获取元素

可以使用 XPath, 也可以使用 CSS 选择器, 推荐优先使用 playwright 提供的几个方法。

getByPlaceholder

通过 placeholder 定位 input 元素


<input type="text" placeholder="请输入账号" />

定位元素并填充内容

await page.getByPlaceholder('请输入账号').fill('account');

getByRole

通过元素的ARIA角色、ARIA属性和可访问名称来定位元素。

第一个参数是 role, 第二个参数是一个配置对象,可以根据不同的限制条件来选择元素

功能很强大的一个选择器,可以选中很多类型的元素

<h3>Sign up</h3>
<label>
  <input type="checkbox" /> Subscribe
</label>
<br/>
<button>Submit</button>

上面的元素通过下面的方式选中

await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();

await page.getByRole('checkbox', { name: 'Subscribe' }).check();

await page.getByRole('button', { name: /submit/i }).click();

getByTestId

通过自定义属性 test id 来定位元素

适合用来确定范围,比如在写组件的时候,可以给最外层增加一个 自定义属性, 之后要选择组件中的元素时,就可以先定位到组件,再去定位里面的元素,

<button data-testid="directions">Itinéraire</button>
await page.getByTestId('directions').click();

getByText

通过文本定位元素

默认是通过包含原则去定位元素的, 要准确定位,通常需要搭配第二个参数 { exact: true }, 来严格匹配

<div>Hello <span>world</span></div>
<div>Hello</div>
// 选中 span
page.getByText('world');

// 选中第一个 div
page.getByText('Hello world');

// 严格匹配 选择第二个 div
page.getByText('Hello', { exact: true });

// 两个div都会被选中
page.getByText(/Hello/);

// 选中第二个 div
page.getByText(/^hello$/i);

getByTitle

通过 title 属性定位元素

<span title='Issues count'>25 issues</span>
await expect(page.getByTitle('Issues count')).toHaveText('25 issues');

getByLabel

通过相关联的<label>aria-labelledby元素的文本或aria-label属性来定位输入元素。

不常用

<input aria-label="Username">
<label for="password-input">Password:</label>
<input id="password-input">
await page.getByLabel('Username').fill('john');
await page.getByLabel('Password').fill('secret');

getByAltText

通过 alt 属性来选择元素

不常用

<img alt='Playwright logo'>
await page.getByAltText('Playwright logo').click();

locator

最基础,也是最强大的一个选择器方法,以上所有的快捷方法都可以被 locator 代替。

语法如下

page.locator(selector);
page.locator(selector, options);

有如下dom

<div class="container">这是一段文字</div>
<span id="span_box">我是span</span>
<div data-testid="test_div">hello 张三</div>
<div title="tooltip">一段提示信息</div>
// 选择 第一个 div
page.locator('.container');
page.locator('div', {
  hasText: '这是一段文字'
});

// 选择 span
page.locator('#span_box');
page.locator('[id="span_box"]');

// 选择第二个 div
page.locator('[data-testid="test_div"]');

// 选择第三个div
page.locator('[title="tooltip"]');

注意: 因为所有的定位方法返回的还是定位器, 所以可以进行链式操作。

以上方法还可以配合 filter、first、 nth 方法使用,从而实现更加精准的定位。

const rowLocator = page.locator('tr');

await page.locator('tr')
    .filter({ hasText: 'text in column 1' })
    .filter({ has: page.getByRole('button', { name: 'column 2 button' }) })
    .screenshot();

page.locator('div').first();

// nth 默认从 0 开始
page.locator('div').nth(2)

获取元素尺寸

有时候需要断言某个元素的大小,就可以使用 boundingBox 方法

const box = await page.getByRole('button').boundingBox();
await page.mouse.click(box.x + box.width / 2, box.y + box.height / 2);