Puppeteer Angular 概要
¥Puppeteer Angular Schematic
将基于 Puppeteer 的 e2e 测试添加到你的 Angular 项目中。
¥Adds Puppeteer-based e2e tests to your Angular project.
新手入门
¥Getting started
在 Angular CLI 应用目录中运行以下命令并按照提示操作。
¥Run the command below in an Angular CLI app directory and follow the prompts.
请注意,这会将原理图添加为项目的依赖。
¥Note this will add the schematic as a dependency to your project.
ng add @puppeteer/ng-schematics
或者你可以使用相同的命令,后跟下面的 options。
¥Or you can use the same command followed by the options below.
目前,该原理图支持以下测试运行程序:
¥Currently, this schematic supports the following test runners:
安装原理图后,你可以运行 E2E 测试:
¥With the schematics installed you can run E2E tests:
ng e2e
选项
¥Options
将原理图添加到项目时,你可以提供以下选项:
¥When adding schematics to your project you can to provide following options:
选项 | 描述 | 值 | 必需的 |
---|---|---|---|
--test-runner | 与 Puppeteer 一起安装的测试框架。 | "jasmine" 、"jest" 、"mocha" 、"node" | true |
创建单个测试文件
¥Creating a single test file
Puppeteer Angular Schematic 公开了一种创建单个测试文件的方法。
¥Puppeteer Angular Schematic exposes a method to create a single test file.
ng generate @puppeteer/ng-schematics:e2e "<TestName>"
同时运行测试服务器和开发服务器
¥Running test server and dev server at the same time
默认情况下,E2E 测试将在与 ng start
相同的端口上运行应用。为了避免这种情况,你可以指定端口并将 angular.json
更新为 e2e
或 puppeteer
(取决于初始设置):
¥By default the E2E test will run the app on the same port as ng start
.
To avoid this you can specify the port the an the angular.json
Update either e2e
or puppeteer
(depending on the initial setup) to:
{
"e2e": {
"builder": "@puppeteer/ng-schematics:puppeteer",
"options": {
"commands": [...],
"devServerTarget": "sandbox:serve",
"testRunner": "<TestRunner>",
"port": 8080
},
...
}
现在将 E2E 测试文件 utils.ts
baseUrl 更新为:
¥Now update the E2E test file utils.ts
baseUrl to:
const baseUrl = 'http://localhost:8080';
贡献
¥Contributing
查看我们的 贡献指南,了解你需要在 Puppeteer 存储库中开发的内容。
¥Check out our contributing guide to get an overview of what you need to develop in the Puppeteer repo.
沙箱冒烟测试
¥Sandbox smoke tests
为了使集成更容易,可以使用单个命令运行冒烟测试,这将创建 Angular 的全新安装(单个应用和 milti 应用项目)。然后它将在其中安装原理图并运行初始 e2e 测试:
¥To make integration easier smoke test can be run with a single command, that will create a fresh install of Angular (single application and a milti application projects). Then it will install the schematics inside them and run the initial e2e tests:
node tools/smoke.mjs
单元测试
¥Unit Testing
该原理图利用 @angular-devkit/schematics/testing
来验证正确的文件创建和 package.json
更新。执行测试套件:
¥The schematics utilize @angular-devkit/schematics/testing
for verifying correct file creation and package.json
updates. To execute the test suit:
npm run test
从 Protractor 迁移
¥Migrating from Protractor
入口点
¥Entry point
Puppeteer 有自己的 browser
来暴露浏览器进程。Protractor 的 browser
的更接近比较是 Puppeteer 的 page
。
¥Puppeteer has its own browser
that exposes the browser process.
A more closes comparison for Protractor's browser
would be Puppeteer's page
.
// Testing framework specific imports
import {setupBrowserHooks, getBrowserState} from './utils';
describe('<Test Name>', function () {
setupBrowserHooks();
it('is running', async function () {
const {page} = getBrowserState();
// Query elements
await page
.locator('my-component')
// Click on the element once found
.click();
});
});
获取元素属性
¥Getting element properties
你可以轻松获取元素的任何属性。
¥You can easily get any property of the element.
// Testing framework specific imports
import {setupBrowserHooks, getBrowserState} from './utils';
describe('<Test Name>', function () {
setupBrowserHooks();
it('is running', async function () {
const {page} = getBrowserState();
// Query elements
const elementText = await page
.locator('.my-component')
.map(button => button.innerText)
// Wait for element to show up
.wait();
// Assert via assertion library
});
});
查询选择器
¥Query Selectors
Puppeteer 支持多种类型的选择器,即 CSS、ARIA、文本、XPath 和 pierce 选择器。下表显示了 Puppeteer 与 Protractor By 的等效项。
¥Puppeteer supports multiple types of selectors, namely, the CSS, ARIA, text, XPath and pierce selectors. The following table shows Puppeteer's equivalents to Protractor By.
为了提高可靠性并减少片状现象,请尝试我们的实验 Locators API
¥For improved reliability and reduced flakiness try our Experimental Locators API
经过 | Protractor 代码 | Puppeteer 查询选择器 |
---|---|---|
CSS(单) | $(by.css('<CSS>')) | page.$('<CSS>') |
CSS(多个) | $$(by.css('<CSS>')) | page.$$('<CSS>') |
ID | $(by.id('<ID>')) | page.$('#<ID>') |
CssContainingText | $(by.cssContainingText('<CSS>', '<TEXT>')) | page.$('<CSS> ::-p-text(<TEXT>)') ` |
DeepCss | $(by.deepCss('<CSS>')) | page.$(':scope >>> <CSS>') |
XPath | $(by.xpath('<XPATH>')) | page.$('::-p-xpath(<XPATH>)') |
JS | $(by.js('document.querySelector("<CSS>")')) | page.evaluateHandle(() => document.querySelector('<CSS>')) |
对于高级用例,例如 Protractor 的
by.addLocator
,你可以检查 Puppeteer 的 自定义选择器。¥For advanced use cases such as Protractor's
by.addLocator
you can check Puppeteer's Custom selectors.
动作选择器
¥Actions Selectors
Puppeteer 允许你执行所有必要的操作来测试你的应用。
¥Puppeteer allows you to all necessary actions to allow test your application.
// Click on the element.
element(locator).click();
// Puppeteer equivalent
await page.locator(locator).click();
// Send keys to the element (usually an input).
element(locator).sendKeys('my text');
// Puppeteer equivalent
await page.locator(locator).fill('my text');
// Clear the text in an element (usually an input).
element(locator).clear();
// Puppeteer equivalent
await page.locator(locator).fill('');
// Get the value of an attribute, for example, get the value of an input.
element(locator).getAttribute('value');
// Puppeteer equivalent
const element = await page.locator(locator).waitHandle();
const value = await element.getProperty('value');
示例
¥Example
量角器测试示例:
¥Sample Protractor test:
describe('Protractor Demo', function () {
it('should add one and two', function () {
browser.get('http://juliemr.github.io/protractor-demo/');
element(by.model('first')).sendKeys(1);
element(by.model('second')).sendKeys(2);
element(by.id('gobutton')).click();
expect(element(by.binding('latest')).getText()).toEqual('3');
});
});
Puppeteer 迁移示例:
¥Sample Puppeteer migration:
import {setupBrowserHooks, getBrowserState} from './utils';
describe('Puppeteer Demo', function () {
setupBrowserHooks();
it('should add one and two', function () {
const {page} = getBrowserState();
await page.goto('http://juliemr.github.io/protractor-demo/');
await page.locator('.form-inline > input:nth-child(1)').fill('1');
await page.locator('.form-inline > input:nth-child(2)').fill('2');
await page.locator('#gobutton').fill('2');
const result = await page
.locator('.table tbody td:last-of-type')
.map(header => header.innerText)
.wait();
expect(result).toEqual('3');
});
});