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