mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix: update documentation for ng-schematics (#11533)
This commit is contained in:
parent
bfdba04bd2
commit
744e8944ac
@ -40,7 +40,7 @@ When adding schematics to your project you can to provide following options:
|
|||||||
Puppeteer Angular Schematic exposes a method to create a single test file.
|
Puppeteer Angular Schematic exposes a method to create a single test file.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ng generate @puppeteer/ng-schematics:test "<TestName>"
|
ng generate @puppeteer/ng-schematics:e2e "<TestName>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running test server and dev server at the same time
|
### Running test server and dev server at the same time
|
||||||
@ -73,32 +73,12 @@ const baseUrl = 'http://localhost:8080';
|
|||||||
|
|
||||||
Check out our [contributing guide](https://pptr.dev/contributing) to get an overview of what you need to develop in the Puppeteer repo.
|
Check out our [contributing guide](https://pptr.dev/contributing) to get an overview of what you need to develop in the Puppeteer repo.
|
||||||
|
|
||||||
### Sandbox
|
### Sandbox smoke tests
|
||||||
|
|
||||||
For easier development we provide a script to auto-generate the Angular project to test against. Simply run:
|
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:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run sandbox -- --init
|
node tools/smoke.mjs
|
||||||
```
|
|
||||||
|
|
||||||
After that to run `@puppeteer/ng-schematics` against the Sandbox Angular project run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox
|
|
||||||
# or to auto-build and then run schematics
|
|
||||||
npm run sandbox -- --build
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the creating of single test schematic:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox:test
|
|
||||||
```
|
|
||||||
|
|
||||||
To create a multi project workspace use the following command
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox -- --init --multi
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Unit Testing
|
### Unit Testing
|
||||||
@ -111,28 +91,52 @@ npm run test
|
|||||||
|
|
||||||
## Migrating from Protractor
|
## Migrating from Protractor
|
||||||
|
|
||||||
### Browser
|
### Entry point
|
||||||
|
|
||||||
Puppeteer has its own [`browser`](https://pptr.dev/api/puppeteer.browser) that exposes different API compared to the one exposed by Protractor.
|
Puppeteer has its own [`browser`](https://pptr.dev/api/puppeteer.browser) that exposes the browser process.
|
||||||
|
A more closes comparison for Protractor's `browser` would be Puppeteer's [`page`](https://pptr.dev/api/puppeteer.page).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import puppeteer from 'puppeteer';
|
// Testing framework specific imports
|
||||||
|
|
||||||
(async () => {
|
import {setupBrowserHooks, getBrowserState} from './utils';
|
||||||
const browser = await puppeteer.launch();
|
|
||||||
|
|
||||||
it('should work', () => {
|
|
||||||
const page = await browser.newPage();
|
|
||||||
|
|
||||||
|
describe('<Test Name>', function () {
|
||||||
|
setupBrowserHooks();
|
||||||
|
it('is running', async function () {
|
||||||
|
const {page} = getBrowserState();
|
||||||
// Query elements
|
// Query elements
|
||||||
const element = await page.$('my-component');
|
await page
|
||||||
|
.locator('my-component')
|
||||||
// Do actions
|
// Click on the element once found
|
||||||
await element.click();
|
.click();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
await browser.close();
|
### Getting element properties
|
||||||
})();
|
|
||||||
|
You can easily get any property of the element.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 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
|
### Query Selectors
|
||||||
@ -154,3 +158,73 @@ The following table shows Puppeteer's equivalents to [Protractor By](https://www
|
|||||||
| JS | `$(by.js('document.querySelector("<CSS>")'))` | `page.evaluateHandle(() => document.querySelector('<CSS>'))` |
|
| JS | `$(by.js('document.querySelector("<CSS>")'))` | `page.evaluateHandle(() => document.querySelector('<CSS>'))` |
|
||||||
|
|
||||||
> For advanced use cases such as Protractor's `by.addLocator` you can check Puppeteer's [Custom selectors](https://pptr.dev/guides/query-selectors#custom-selectors).
|
> For advanced use cases such as Protractor's `by.addLocator` you can check Puppeteer's [Custom selectors](https://pptr.dev/guides/query-selectors#custom-selectors).
|
||||||
|
|
||||||
|
### Actions Selectors
|
||||||
|
|
||||||
|
Puppeteer allows you to all necessary actions to allow test your application.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 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:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Sample Puppeteer migration:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
2178
package-lock.json
generated
2178
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
1
packages/ng-schematics/.gitignore
vendored
1
packages/ng-schematics/.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# Sandbox
|
# Sandbox
|
||||||
sandbox/
|
sandbox/
|
||||||
multi/
|
|
||||||
|
@ -40,7 +40,7 @@ When adding schematics to your project you can to provide following options:
|
|||||||
Puppeteer Angular Schematic exposes a method to create a single test file.
|
Puppeteer Angular Schematic exposes a method to create a single test file.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ng generate @puppeteer/ng-schematics:test "<TestName>"
|
ng generate @puppeteer/ng-schematics:e2e "<TestName>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running test server and dev server at the same time
|
### Running test server and dev server at the same time
|
||||||
@ -73,32 +73,12 @@ const baseUrl = 'http://localhost:8080';
|
|||||||
|
|
||||||
Check out our [contributing guide](https://pptr.dev/contributing) to get an overview of what you need to develop in the Puppeteer repo.
|
Check out our [contributing guide](https://pptr.dev/contributing) to get an overview of what you need to develop in the Puppeteer repo.
|
||||||
|
|
||||||
### Sandbox
|
### Sandbox smoke tests
|
||||||
|
|
||||||
For easier development we provide a script to auto-generate the Angular project to test against. Simply run:
|
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:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run sandbox -- --init
|
node tools/smoke.mjs
|
||||||
```
|
|
||||||
|
|
||||||
After that to run `@puppeteer/ng-schematics` against the Sandbox Angular project run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox
|
|
||||||
# or to auto-build and then run schematics
|
|
||||||
npm run sandbox -- --build
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the creating of single test schematic:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox:test
|
|
||||||
```
|
|
||||||
|
|
||||||
To create a multi project workspace use the following command
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox -- --init --multi
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Unit Testing
|
### Unit Testing
|
||||||
@ -111,28 +91,52 @@ npm run test
|
|||||||
|
|
||||||
## Migrating from Protractor
|
## Migrating from Protractor
|
||||||
|
|
||||||
### Browser
|
### Entry point
|
||||||
|
|
||||||
Puppeteer has its own [`browser`](https://pptr.dev/api/puppeteer.browser) that exposes different API compared to the one exposed by Protractor.
|
Puppeteer has its own [`browser`](https://pptr.dev/api/puppeteer.browser) that exposes the browser process.
|
||||||
|
A more closes comparison for Protractor's `browser` would be Puppeteer's [`page`](https://pptr.dev/api/puppeteer.page).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import puppeteer from 'puppeteer';
|
// Testing framework specific imports
|
||||||
|
|
||||||
(async () => {
|
import {setupBrowserHooks, getBrowserState} from './utils';
|
||||||
const browser = await puppeteer.launch();
|
|
||||||
|
|
||||||
it('should work', () => {
|
|
||||||
const page = await browser.newPage();
|
|
||||||
|
|
||||||
|
describe('<Test Name>', function () {
|
||||||
|
setupBrowserHooks();
|
||||||
|
it('is running', async function () {
|
||||||
|
const {page} = getBrowserState();
|
||||||
// Query elements
|
// Query elements
|
||||||
const element = await page.$('my-component');
|
await page
|
||||||
|
.locator('my-component')
|
||||||
// Do actions
|
// Click on the element once found
|
||||||
await element.click();
|
.click();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
await browser.close();
|
### Getting element properties
|
||||||
})();
|
|
||||||
|
You can easily get any property of the element.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 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
|
### Query Selectors
|
||||||
@ -154,3 +158,73 @@ The following table shows Puppeteer's equivalents to [Protractor By](https://www
|
|||||||
| JS | `$(by.js('document.querySelector("<CSS>")'))` | `page.evaluateHandle(() => document.querySelector('<CSS>'))` |
|
| JS | `$(by.js('document.querySelector("<CSS>")'))` | `page.evaluateHandle(() => document.querySelector('<CSS>'))` |
|
||||||
|
|
||||||
> For advanced use cases such as Protractor's `by.addLocator` you can check Puppeteer's [Custom selectors](https://pptr.dev/guides/query-selectors#custom-selectors).
|
> For advanced use cases such as Protractor's `by.addLocator` you can check Puppeteer's [Custom selectors](https://pptr.dev/guides/query-selectors#custom-selectors).
|
||||||
|
|
||||||
|
### Actions Selectors
|
||||||
|
|
||||||
|
Puppeteer allows you to all necessary actions to allow test your application.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 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:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Sample Puppeteer migration:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
@ -56,14 +56,14 @@
|
|||||||
"node": ">=16.13.2"
|
"node": ">=16.13.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/architect": "^0.1602.10",
|
"@angular-devkit/architect": "^0.1700.6",
|
||||||
"@angular-devkit/core": "^16.2.10",
|
"@angular-devkit/core": "^17.0.6",
|
||||||
"@angular-devkit/schematics": "^16.2.10"
|
"@angular-devkit/schematics": "^17.0.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.18.61",
|
"@types/node": "^16.18.61",
|
||||||
"@schematics/angular": "^16.2.10",
|
"@schematics/angular": "^17.0.6",
|
||||||
"@angular/cli": "^16.2.10",
|
"@angular/cli": "^17.0.6",
|
||||||
"rxjs": "7.8.1"
|
"rxjs": "7.8.1"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
|
@ -55,8 +55,8 @@ function parseUserTestArgs(userArgs: Record<string, string>): SchematicsSpec {
|
|||||||
options['route'] = userArgs['r'];
|
options['route'] = userArgs['r'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options['route'] && !options['route'].startsWith('/')) {
|
if (options['route'] && options['route'].startsWith('/')) {
|
||||||
options['route'] = `/${options['route']}`;
|
options['route'] = options['route'].substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options as SchematicsSpec;
|
return options as SchematicsSpec;
|
||||||
|
@ -10,8 +10,7 @@ describe('App test', function () {
|
|||||||
setupBrowserHooks();
|
setupBrowserHooks();
|
||||||
it('is running', async function () {
|
it('is running', async function () {
|
||||||
const {page} = getBrowserState();
|
const {page} = getBrowserState();
|
||||||
const element = await page.waitForSelector('text/<%= project %>');
|
const element = await page.locator('::-p-text(<%= project %>)').wait();
|
||||||
|
|
||||||
<% if(testRunner == 'jasmine' || testRunner == 'jest') { %>
|
<% if(testRunner == 'jasmine' || testRunner == 'jest') { %>
|
||||||
expect(element).not.toBeNull();
|
expect(element).not.toBeNull();
|
||||||
<% } %><% if(testRunner == 'mocha' || testRunner == 'node') { %>
|
<% } %><% if(testRunner == 'mocha' || testRunner == 'node') { %>
|
||||||
|
@ -7,7 +7,7 @@ const baseUrl = process.env['baseUrl'] ?? '<%= baseUrl %>';
|
|||||||
let browser: puppeteer.Browser;
|
let browser: puppeteer.Browser;
|
||||||
let page: puppeteer.Page;
|
let page: puppeteer.Page;
|
||||||
|
|
||||||
export function setupBrowserHooks(path = '/'): void {
|
export function setupBrowserHooks(path = ''): void {
|
||||||
<% if(testRunner == 'jasmine' || testRunner == 'jest') { %>
|
<% if(testRunner == 'jasmine' || testRunner == 'jest') { %>
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
browser = await puppeteer.launch({
|
browser = await puppeteer.launch({
|
||||||
|
@ -107,7 +107,7 @@ function getProjectBaseUrl(project: any, port: number): string {
|
|||||||
options.protocol = projectOptions.ssl ? 'https' : 'http';
|
options.protocol = projectOptions.ssl ? 'https' : 'http';
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${options.protocol}://${options.host}:${options.port}`;
|
return `${options.protocol}://${options.host}:${options.port}/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTsConfigPath(project: AngularProject): string {
|
function getTsConfigPath(project: AngularProject): string {
|
||||||
|
@ -35,7 +35,7 @@ describe('@puppeteer/ng-schematics: e2e', () => {
|
|||||||
});
|
});
|
||||||
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
||||||
expect(tree.readContent('/e2e/tests/my-test.e2e.ts')).toContain(
|
expect(tree.readContent('/e2e/tests/my-test.e2e.ts')).toContain(
|
||||||
`setupBrowserHooks('/${route}');`
|
`setupBrowserHooks('${route}');`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ describe('@puppeteer/ng-schematics: e2e', () => {
|
|||||||
});
|
});
|
||||||
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
||||||
expect(tree.readContent('/e2e/tests/my-test.e2e.ts')).toContain(
|
expect(tree.readContent('/e2e/tests/my-test.e2e.ts')).toContain(
|
||||||
`setupBrowserHooks('${route}');`
|
`setupBrowserHooks('home');`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -89,7 +89,7 @@ describe('@puppeteer/ng-schematics: e2e', () => {
|
|||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tree.readContent(getMultiApplicationFile('e2e/tests/my-test.e2e.ts'))
|
tree.readContent(getMultiApplicationFile('e2e/tests/my-test.e2e.ts'))
|
||||||
).toContain(`setupBrowserHooks('/${route}');`);
|
).toContain(`setupBrowserHooks('${route}');`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create with route with starting slash', async () => {
|
it('should create with route with starting slash', async () => {
|
||||||
@ -103,7 +103,7 @@ describe('@puppeteer/ng-schematics: e2e', () => {
|
|||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
tree.readContent(getMultiApplicationFile('e2e/tests/my-test.e2e.ts'))
|
tree.readContent(getMultiApplicationFile('e2e/tests/my-test.e2e.ts'))
|
||||||
).toContain(`setupBrowserHooks('${route}');`);
|
).toContain(`setupBrowserHooks('home');`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,15 +9,17 @@ if (process.env.CI) {
|
|||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
runNgSchematicsSandbox({
|
runNgSchematicsSandbox({
|
||||||
|
isMulti: false,
|
||||||
isInit: true,
|
isInit: true,
|
||||||
}),
|
}),
|
||||||
runNgSchematicsSandbox({
|
runNgSchematicsSandbox({
|
||||||
isInit: true,
|
|
||||||
isMulti: true,
|
isMulti: true,
|
||||||
|
isInit: true,
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await runNgSchematicsSandbox({
|
await runNgSchematicsSandbox({
|
||||||
|
isMulti: false,
|
||||||
isSmoke: true,
|
isSmoke: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ When adding schematics to your project you can to provide following options:
|
|||||||
Puppeteer Angular Schematic exposes a method to create a single test file.
|
Puppeteer Angular Schematic exposes a method to create a single test file.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ng generate @puppeteer/ng-schematics:test "<TestName>"
|
ng generate @puppeteer/ng-schematics:e2e "<TestName>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running test server and dev server at the same time
|
### Running test server and dev server at the same time
|
||||||
@ -73,32 +73,12 @@ const baseUrl = 'http://localhost:8080';
|
|||||||
|
|
||||||
Check out our [contributing guide](https://pptr.dev/contributing) to get an overview of what you need to develop in the Puppeteer repo.
|
Check out our [contributing guide](https://pptr.dev/contributing) to get an overview of what you need to develop in the Puppeteer repo.
|
||||||
|
|
||||||
### Sandbox
|
### Sandbox smoke tests
|
||||||
|
|
||||||
For easier development we provide a script to auto-generate the Angular project to test against. Simply run:
|
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:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run sandbox -- --init
|
node tools/smoke.mjs
|
||||||
```
|
|
||||||
|
|
||||||
After that to run `@puppeteer/ng-schematics` against the Sandbox Angular project run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox
|
|
||||||
# or to auto-build and then run schematics
|
|
||||||
npm run sandbox -- --build
|
|
||||||
```
|
|
||||||
|
|
||||||
To run the creating of single test schematic:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox:test
|
|
||||||
```
|
|
||||||
|
|
||||||
To create a multi project workspace use the following command
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run sandbox -- --init --multi
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Unit Testing
|
### Unit Testing
|
||||||
@ -111,28 +91,52 @@ npm run test
|
|||||||
|
|
||||||
## Migrating from Protractor
|
## Migrating from Protractor
|
||||||
|
|
||||||
### Browser
|
### Entry point
|
||||||
|
|
||||||
Puppeteer has its own [`browser`](https://pptr.dev/api/puppeteer.browser) that exposes different API compared to the one exposed by Protractor.
|
Puppeteer has its own [`browser`](https://pptr.dev/api/puppeteer.browser) that exposes the browser process.
|
||||||
|
A more closes comparison for Protractor's `browser` would be Puppeteer's [`page`](https://pptr.dev/api/puppeteer.page).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import puppeteer from 'puppeteer';
|
// Testing framework specific imports
|
||||||
|
|
||||||
(async () => {
|
import {setupBrowserHooks, getBrowserState} from './utils';
|
||||||
const browser = await puppeteer.launch();
|
|
||||||
|
|
||||||
it('should work', () => {
|
|
||||||
const page = await browser.newPage();
|
|
||||||
|
|
||||||
|
describe('<Test Name>', function () {
|
||||||
|
setupBrowserHooks();
|
||||||
|
it('is running', async function () {
|
||||||
|
const {page} = getBrowserState();
|
||||||
// Query elements
|
// Query elements
|
||||||
const element = await page.$('my-component');
|
await page
|
||||||
|
.locator('my-component')
|
||||||
// Do actions
|
// Click on the element once found
|
||||||
await element.click();
|
.click();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
await browser.close();
|
### Getting element properties
|
||||||
})();
|
|
||||||
|
You can easily get any property of the element.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 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
|
### Query Selectors
|
||||||
@ -154,3 +158,73 @@ The following table shows Puppeteer's equivalents to [Protractor By](https://www
|
|||||||
| JS | `$(by.js('document.querySelector("<CSS>")'))` | `page.evaluateHandle(() => document.querySelector('<CSS>'))` |
|
| JS | `$(by.js('document.querySelector("<CSS>")'))` | `page.evaluateHandle(() => document.querySelector('<CSS>'))` |
|
||||||
|
|
||||||
> For advanced use cases such as Protractor's `by.addLocator` you can check Puppeteer's [Custom selectors](https://pptr.dev/guides/query-selectors#custom-selectors).
|
> For advanced use cases such as Protractor's `by.addLocator` you can check Puppeteer's [Custom selectors](https://pptr.dev/guides/query-selectors#custom-selectors).
|
||||||
|
|
||||||
|
### Actions Selectors
|
||||||
|
|
||||||
|
Puppeteer allows you to all necessary actions to allow test your application.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 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:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Sample Puppeteer migration:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user