mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-05-04 20:59:19 +08:00
docs(tutorial): update tutorial steps to discuss protractor
Closes #6940
This commit is contained in:
@@ -150,7 +150,13 @@ are working on the code.
|
||||
## Running End to End Tests
|
||||
|
||||
The project is preconfigured to use [Protractor][protractor] to run the end to end tests for the
|
||||
application. Execute the Protractor test scripts against your application by running:
|
||||
application. Set up the binaries protractor needs to run by running:
|
||||
|
||||
```
|
||||
npm run update-webdriver
|
||||
```
|
||||
(You will only need to do this once) Execute the Protractor test scripts against your application
|
||||
by running:
|
||||
|
||||
```
|
||||
npm run protractor
|
||||
|
||||
@@ -96,18 +96,23 @@ describe('PhoneCat App', function() {
|
||||
describe('Phone list view', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser().navigateTo('../../app/index.html');
|
||||
browser.get('app/index.html');
|
||||
});
|
||||
|
||||
|
||||
it('should filter the phone list as user types into the search box', function() {
|
||||
expect(repeater('.phones li').count()).toBe(3);
|
||||
|
||||
input('query').enter('nexus');
|
||||
expect(repeater('.phones li').count()).toBe(1);
|
||||
var phoneList = element.all(by.repeater('phone in phones'));
|
||||
var query = element(by.model('query'));
|
||||
|
||||
input('query').enter('motorola');
|
||||
expect(repeater('.phones li').count()).toBe(2);
|
||||
expect(phoneList.count()).toBe(3);
|
||||
|
||||
query.sendKeys('nexus');
|
||||
expect(phoneList.count()).toBe(1);
|
||||
|
||||
query.clear();
|
||||
query.sendKeys('motorola');
|
||||
expect(phoneList.count()).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -117,20 +122,14 @@ Even though the syntax of this test looks very much like our controller unit tes
|
||||
Jasmine, the end-to-end test uses APIs of {@link guide/dev_guide.e2e-testing Angular's end-to-end
|
||||
test runner}.
|
||||
|
||||
To run the end-to-end test, open one of the following in a new browser tab:
|
||||
Much like Karma is the test runner for unit tests, we use Protractor to run end-to-end tests.
|
||||
Try it with `npm run protractor`. End-to-end tests are slow, so unlike with unit tests, Protractor
|
||||
will exit after the test run and will not automatically rerun the test suite on every file change.
|
||||
To rerun the test suite, execute `npm run protractor` again.
|
||||
|
||||
* node.js users: http://localhost:8000/test/e2e/runner.html
|
||||
* users with other http servers:
|
||||
`http://localhost:[port-number]/[context-path]/test/e2e/runner.html`
|
||||
* casual reader: http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html
|
||||
|
||||
Previously we've seen how Karma can be used to execute unit tests. Well, it can also run the
|
||||
end-to-end tests! Use `./scripts/e2e-test.sh` (if you are on Windows, run `scripts\e2e-test.bat`) script for that. End-to-end tests are slow, so unlike
|
||||
with unit tests, Karma will exit after the test run and will not automatically rerun the test
|
||||
suite on every file change. To rerun the test suite, execute the `e2e-test.sh` or `e2e-test.bat` script again.
|
||||
|
||||
Note: You must ensure you've installed the karma-ng-scenario framework plugin prior to running the
|
||||
`e2e-test.sh` script. You can do this by issuing `npm install` into your terminal.
|
||||
Note: You must ensure you've installed the protractor and updated webdriver prior to running the
|
||||
`npm run protractor`. You can do this by issuing `npm install` and `npm run update-webdriver` into
|
||||
your terminal.
|
||||
|
||||
This test verifies that the search box and the repeater are correctly wired together. Notice how
|
||||
easy it is to write end-to-end tests in Angular. Although this example is for a simple test, it
|
||||
@@ -173,28 +172,24 @@ ngBindTemplate} directives, which are invisible to the user while the page is lo
|
||||
```js
|
||||
it('should display the current filter value within an element with id "status"',
|
||||
function() {
|
||||
expect(element('#status').text()).toMatch(/Current filter: \s*$/);
|
||||
var statusElement = element(by.id('status'));
|
||||
expect(statusElement.getText()).toMatch(/Current filter: \s*$/);
|
||||
|
||||
input('query').enter('nexus');
|
||||
element(by.model('query')).sendKeys('nexus');
|
||||
|
||||
expect(element('#status').text()).toMatch(/Current filter: nexus\s*$/);
|
||||
expect(statusElement.getText()).toMatch(/Current filter: nexus\s*$/);
|
||||
|
||||
//alternative version of the last assertion that tests just the value of the binding
|
||||
using('#status').expect(binding('query')).toBe('nexus');
|
||||
expect(statusElement.element(by.binding('query'))).toBe('nexus');
|
||||
});
|
||||
```
|
||||
|
||||
Refresh the browser tab with the end-to-end test runner to see the test fail. To make the test
|
||||
pass, edit the `index.html` template to add a `div` or `p` element with `id` `"status"` and content
|
||||
with the `query` binding, prefixed by "Current filter:". For instance:
|
||||
Re-run `npm run protractor` to see the test fail. To make the test pass, edit the `index.html`
|
||||
template to add a `div` or `p` element with `id` `"status"` and content with the `query` binding,
|
||||
prefixed by "Current filter:". For instance:
|
||||
|
||||
<div id="status">Current filter: {{query}}</div>
|
||||
|
||||
* Add a `pause()` statement inside of an end-to-end test and rerun it. You'll see the runner pause;
|
||||
this gives you the opportunity to explore the state of your application while it is displayed in
|
||||
the browser. The app is live! You can change the search query to prove it. Notice how useful this
|
||||
is for troubleshooting end-to-end tests.
|
||||
|
||||
|
||||
# Summary
|
||||
|
||||
|
||||
@@ -152,28 +152,36 @@ __`test/e2e/scenarios.js`:__
|
||||
|
||||
```js
|
||||
...
|
||||
it('should be possible to control phone order via the drop down select box',
|
||||
function() {
|
||||
//let's narrow the dataset to make the test assertions shorter
|
||||
input('query').enter('tablet');
|
||||
it('should be possible to control phone order via the drop down select box', function() {
|
||||
|
||||
expect(repeater('.phones li', 'Phone List').column('phone.name')).
|
||||
toEqual(["Motorola XOOM\u2122 with Wi-Fi",
|
||||
"MOTOROLA XOOM\u2122"]);
|
||||
var phoneNameColumn = element.all(by.repeater('phone in phones').column('{{phone.name}}'));
|
||||
var query = element(by.model('query'));
|
||||
|
||||
select('orderProp').option('Alphabetical');
|
||||
function getNames() {
|
||||
return phoneNameColumn.map(function(elm) {
|
||||
return elm.getText();
|
||||
});
|
||||
}
|
||||
|
||||
expect(repeater('.phones li', 'Phone List').column('phone.name')).
|
||||
toEqual(["MOTOROLA XOOM\u2122",
|
||||
"Motorola XOOM\u2122 with Wi-Fi"]);
|
||||
});
|
||||
...
|
||||
query.sendKeys('tablet'); //let's narrow the dataset to make the test assertions shorter
|
||||
|
||||
expect(getNames()).toEqual([
|
||||
"Motorola XOOM\u2122 with Wi-Fi",
|
||||
"MOTOROLA XOOM\u2122"
|
||||
]);
|
||||
|
||||
element(by.model('orderProp')).findElement(by.css('option[value="name"]')).click();
|
||||
|
||||
expect(getNames()).toEqual([
|
||||
"MOTOROLA XOOM\u2122",
|
||||
"Motorola XOOM\u2122 with Wi-Fi"
|
||||
]);
|
||||
});...
|
||||
```
|
||||
|
||||
The end-to-end test verifies that the ordering mechanism of the select box is working correctly.
|
||||
|
||||
You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
|
||||
`runner.html` to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-4/test/e2e/runner.html).
|
||||
You can now rerun `npm run protractor` to see the tests run.
|
||||
|
||||
# Experiments
|
||||
|
||||
|
||||
@@ -76,9 +76,12 @@ __`test/e2e/scenarios.js`__:
|
||||
```js
|
||||
...
|
||||
it('should render phone specific links', function() {
|
||||
input('query').enter('nexus');
|
||||
element('.phones li a').click();
|
||||
expect(browser().location().url()).toBe('/phones/nexus-s');
|
||||
var query = element(by.model('query'));
|
||||
query.sendKeys('nexus');
|
||||
element(by.css('.phones li a')).click();
|
||||
browser.getLocationAbsUrl().then(function(url) {
|
||||
expect(url.split('#')[1]).toBe('/phones/nexus-s');
|
||||
});
|
||||
});
|
||||
...
|
||||
```
|
||||
@@ -86,8 +89,7 @@ __`test/e2e/scenarios.js`__:
|
||||
We added a new end-to-end test to verify that the app is generating correct links to the phone
|
||||
views that we will implement in the upcoming steps.
|
||||
|
||||
You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
|
||||
runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-6/test/e2e/runner.html).
|
||||
You can now rerun `npm run protractor` to see the tests run.
|
||||
|
||||
|
||||
# Experiments
|
||||
|
||||
@@ -267,22 +267,21 @@ to various URLs and verify that the correct view was rendered.
|
||||
});
|
||||
...
|
||||
|
||||
describe('Phone detail view', function() {
|
||||
describe('Phone detail view', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser().navigateTo('app/index.html#/phones/nexus-s');
|
||||
browser.get('app/index.html#/phones/nexus-s');
|
||||
});
|
||||
|
||||
|
||||
it('should display placeholder page with phoneId', function() {
|
||||
expect(binding('phoneId')).toBe('nexus-s');
|
||||
expect(element(by.binding('phoneId')).getText()).toBe('nexus-s');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
|
||||
runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-7/test/e2e/runner.html).
|
||||
You can now rerun `npm run protractor` to see the tests run.
|
||||
|
||||
|
||||
# Experiments
|
||||
|
||||
@@ -166,20 +166,19 @@ __`test/e2e/scenarios.js`:__
|
||||
describe('Phone detail view', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser().navigateTo('../../app/index.html#/phones/nexus-s');
|
||||
browser.get('app/index.html#/phones/nexus-s');
|
||||
});
|
||||
|
||||
|
||||
it('should display nexus-s page', function() {
|
||||
expect(binding('phone.name')).toBe('Nexus S');
|
||||
expect(element(by.binding('phone.name')).getText()).toBe('Nexus S');
|
||||
});
|
||||
});
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
|
||||
runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-8/test/e2e/runner.html).
|
||||
You can now rerun `npm run protractor` to see the tests run.
|
||||
|
||||
|
||||
# Experiments
|
||||
|
||||
@@ -90,23 +90,22 @@ __`test/e2e/scenarios.js`:__
|
||||
...
|
||||
|
||||
it('should display the first phone image as the main phone image', function() {
|
||||
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.0.jpg');
|
||||
expect(element(by.css('img.phone')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
|
||||
});
|
||||
|
||||
|
||||
it('should swap main image if a thumbnail image is clicked on', function() {
|
||||
element('.phone-thumbs li:nth-child(3) img').click();
|
||||
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.2.jpg');
|
||||
element(by.css('.phone-thumbs li:nth-child(3) img')).click();
|
||||
expect(element(by.css('img.phone')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);
|
||||
|
||||
element('.phone-thumbs li:nth-child(1) img').click();
|
||||
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.0.jpg');
|
||||
element(by.css('.phone-thumbs li:nth-child(1) img')).click();
|
||||
expect(element(by.css('img.phone')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
You can now rerun `./scripts/e2e-test.sh` or refresh the browser tab with the end-to-end test
|
||||
runner to see the tests run, or you can see them running on [Angular's server](http://angular.github.com/angular-phonecat/step-10/test/e2e/runner.html).
|
||||
You can now rerun `npm run protractor` to see the tests run.
|
||||
|
||||
|
||||
# Experiments
|
||||
|
||||
|
||||
Reference in New Issue
Block a user