Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit e51f0ec

Browse files
authored
fix(doc): update doc for testing with node 8 async/await and chrome inspector. (#4613)
1 parent 5d13b00 commit e51f0ec

File tree

10 files changed

+276
-84
lines changed

10 files changed

+276
-84
lines changed

debugging/async_await.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
describe('angularjs homepage', function() {
2+
it('should greet the named user', async function() {
3+
debugger;
4+
await browser.get('http://www.angularjs.org');
5+
6+
await element(by.model('yourName')).sendKeys('Julie');
7+
8+
var greeting = element(by.binding('yourName'));
9+
10+
expect(await greeting.getText()).toEqual('Hello Julie!');
11+
});
12+
13+
describe('todo list', function() {
14+
var todoList;
15+
16+
beforeEach(async function() {
17+
await browser.get('http://www.angularjs.org');
18+
todoList = element.all(by.repeater('todo in todoList.todos'));
19+
});
20+
21+
it('should list todos', async function() {
22+
expect(await todoList.count()).toEqual(2);
23+
expect(await todoList.get(1).getText()).toEqual('build an AngularJS app');
24+
});
25+
26+
it('should add a todo', async function() {
27+
var addTodo = element(by.model('todoList.todoText'));
28+
var addButton = element(by.css('[value="add"]'));
29+
30+
await addTodo.sendKeys('write a protractor test');
31+
await addButton.click();
32+
33+
expect(await todoList.count()).toEqual(3);
34+
expect(await todoList.get(2).getText()).toEqual('write a protractor test');
35+
});
36+
});
37+
});

debugging/conf.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// An example configuration file for debugging test using async/await.
2+
exports.config = {
3+
directConnect: true,
4+
5+
// Capabilities to be passed to the webdriver instance.
6+
capabilities: {
7+
'browserName': 'chrome'
8+
},
9+
10+
seleniumAddress: 'http://localhost:4444/wd/hub',
11+
12+
// Framework to use. Jasmine is recommended.
13+
framework: 'jasmine',
14+
15+
// Spec patterns are relative to the current working directory when
16+
// protractor is called.
17+
specs: ['async_await.js'],
18+
19+
SELENIUM_PROMISE_MANAGER: false,
20+
21+
// Options to be passed to Jasmine.
22+
jasmineNodeOpts: {
23+
defaultTimeoutInterval: 30000
24+
}
25+
};

docs/async-await.md

+83-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,86 @@
11
`async`/`await`
22
===============
33

4-
Please see [our TypeScript examples which use `async`/`await`](/exampleTypescript/asyncAwait/).
4+
**Background**
5+
6+
- The Web Driver Control Flow is used to synchronize your commands so they reach
7+
the browser in the correct order (see
8+
[/docs/control-flow.md](/docs/control-flow.md) for details). In the future, the
9+
control flow is being removed (see [SeleniumHQ's github issue](
10+
https://github.com/SeleniumHQ/selenium/issues/2969) for details). Instead of the
11+
control flow, you can synchronize your commands with promise chaining or the
12+
upcoming ES7 feature `async`/`await`.
13+
14+
- Previously, we have Typescript support for `async`/`await`: Please see [TypeScript examples which use `async`/`await`](/exampleTypescript/asyncAwait/README.md).
15+
16+
- The latest [Node.js](https://nodejs.org/en/) provides native async/await,
17+
which means we can get stable e2e test without using control flow in javascript test.
18+
19+
**Note**: To write and run native async/await test, the node.js version should be greater than or equal to 8.0, and Jasmine version should be greater than or equal to 2.7
20+
21+
- If we disable control flow and use async/await to write tests, we can get a
22+
better debugging experience by using [chrome
23+
inspector](./debugging.md#disabled-control-flow)
24+
25+
**How to use native async/await in test**
26+
27+
We have a simple example to show how to use async/await in test.
28+
29+
You can find the whole example in
30+
[here](/debugging/async_await.js)
31+
32+
```javascript
33+
describe('angularjs homepage', function() {
34+
it('should greet the named user', async function() {
35+
await browser.get('http://www.angularjs.org');
36+
37+
await element(by.model('yourName')).sendKeys('Julie');
38+
39+
var greeting = element(by.binding('yourName'));
40+
41+
expect(await greeting.getText()).toEqual('Hello Julie!');
42+
});
43+
```
44+
45+
As you can see, the syntax is almost the same with TypeScript async/await.
46+
47+
1. We need wrap our asynchronous function with “async”.
48+
1. We can add “await” keyword to each operation that we want our program to
49+
wait for.
50+
51+
**Note:** Never forget to add “await” keyword in an async function, it
52+
may bring some unexpected problem (e.g. your test might fail silently and
53+
always be reported as passed).
54+
1. Don’t forget to turn off control_flow, you cannot use a mix of `async`/`await` and the control flow:
55+
`async`/`await` causes the control flow to become unreliable (see
56+
[github issue]( https://github.com/SeleniumHQ/selenium/issues/3037)). So if you
57+
`async`/`await` anywhere in a spec, you should use the
58+
`SELENIUM_PROMISE_MANAGER: false`
59+
60+
```javascript
61+
// An example configuration file for debugging test using async/await.
62+
exports.config = {
63+
directConnect: true,
64+
65+
// Capabilities to be passed to the webdriver instance.
66+
capabilities: {
67+
'browserName': 'chrome'
68+
},
69+
70+
seleniumAddress: 'http://localhost:4444/wd/hub',
71+
72+
// Framework to use. Jasmine is recommended.
73+
framework: 'jasmine',
74+
75+
// Spec patterns are relative to the current working directory when
76+
// protractor is called.
77+
specs: ['async_await.js'],
78+
79+
SELENIUM_PROMISE_MANAGER: false,
80+
81+
// Options to be passed to Jasmine.
82+
jasmineNodeOpts: {
83+
defaultTimeoutInterval: 30000
84+
}
85+
};
86+
```

docs/breakpoint.png

96.4 KB
Loading

docs/chromeDevTool.png

61.7 KB
Loading

docs/debugging.md

+121-59
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ state of the application they're testing. WebDriver tests in particular
77
can be difficult to debug because of long error messages and the separation
88
between the browser and the process running the test.
99

10-
Types of Failure
11-
----------------
10+
## Types of Failure
1211

1312
Protractor comes with examples of failing tests ([failure_spec.js](https://github.com/angular/protractor/blob/master/debugging/failure_spec.js)).
1413
To run, start up the test application and a Selenium Server, and run the command below. Then look at all the stack traces.
@@ -28,15 +27,125 @@ This test suite shows various types of failure:
2827
like.
2928

3029

31-
Timeouts
32-
--------
30+
## Timeouts
3331

3432
There are several ways that Protractor can time out. See the [Timeouts](/docs/timeouts.md)
3533
reference for full documentation.
3634

35+
## Disabled Control Flow
3736

38-
Pausing to Debug
39-
----------------
37+
38+
The latest [Node.js](https://nodejs.org/en/) provides native async/await, which
39+
means we can get stable e2e test easily without using control flow. Furthermore,
40+
if we write our test by using async/await[(how to?)](./async-await.md), we can
41+
use chrome development tool and chrome inspector together to debug the new
42+
tests, which will give a nicer debugging experience.
43+
44+
**Debuging tests in chrome inspector**
45+
46+
We can debug both javascript and TypeScript async/await tests in chrome
47+
inspector and the debugging process is almost the same.
48+
49+
We have a simple example to show how to debug async/await in test. You can find
50+
the whole example in
51+
[here](../debugging/async_await.js)
52+
53+
- Add “debugger” keyword to the test case that we want to debug.
54+
55+
```javascript
56+
it('should greet the named user', async function() {
57+
debugger;
58+
await browser.get('http://www.angularjs.org');
59+
60+
await element(by.model('yourName')).sendKeys('Julie');
61+
62+
var greeting = element(by.binding('yourName'));
63+
64+
expect(await greeting.getText()).toEqual('Hello Julie!');
65+
});
66+
```
67+
68+
- Start test process with a new argument "inspect-brk", which will enable
69+
inspector agent, listen on default address and port (127.0.0.1:9229) and
70+
break before user code starts
71+
72+
Use
73+
74+
```
75+
node --inspect-brk bin/protractor <config_file>
76+
```
77+
78+
- Open chrome inspector: Enter "chrome://inspect/#devices" in browser, find
79+
the current running target and click “Inspect”
80+
81+
![screenshot](./inspector.png)
82+
83+
- The test will start and pause at the beginning.
84+
85+
![screenshot](./firstBreak.png)
86+
87+
- We can click F8 (resume script execution), and the test will pause at the
88+
first line that has our “debuggerkeyword. We can then add breakpoints and
89+
debug tests.
90+
91+
![screenshot](./breakpoint.png)
92+
93+
- We can also open chrome development tool on the webdriver controlled browser
94+
to check the html elements and do some queries while the test execution is
95+
pausing.
96+
97+
![screenshot](./chromeDevTool.png)
98+
99+
- Known Issues
100+
101+
1. If we resume test execution after a long time pause, it will jump to next
102+
test case even we have some other breaking points in current test case since
103+
current test case has already been timeout. You can set
104+
jasmine.DEFAULT_TIMEOUT_INTERVAL to an arbitrary high value so that your
105+
test doesn't time out.
106+
107+
2. If we step into protractor lib code which was written in Typescript, we
108+
cannot see the TypeScript code. In general, you can add breakpoints to each
109+
line that you want it to pause, and use F8 (resume script execution) to
110+
debug(To avoid step into protractor lib).
111+
112+
113+
**Setting Up VSCode for Debugging**
114+
115+
VS Code has built-in [debugging](https://code.visualstudio.com/docs/editor/debugging) support for the Node.js runtime and can debug JavaScript, TypeScript, and any other language that gets transpiled to JavaScript.
116+
117+
To set up VSCode for Protractor, follow the below steps:
118+
119+
1. Click on the Debugging icon in the View Bar on the side of VS Code.
120+
2. Click on the Configure gear icon on the Debug view top bar and choose nodejs environment.
121+
3. It will generate a `launch.json` file under your workspace's `.vscode` folder.
122+
4. Setup your launch.json file by configuring below two commands:
123+
```
124+
"program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
125+
"args": ["${workspaceRoot}/protractorConfig.js"],
126+
```
127+
5. Save your launch.json, put some breakpoints and start debugging.
128+
129+
**Setting Up WebStorm for Debugging**
130+
131+
To set up WebStorm for Protractor, do the following:
132+
133+
1. Open the Run/Debug Configurations dialog
134+
2. Add new Node.js configuration.
135+
3. On the Configuration tab set:
136+
- **Node Interpreter**: path to node executable
137+
- **Working directory**: your project base path
138+
- **JavaScript file**: path to Protractor cli.js file (e.g. *node_modules\protractor\built\cli.js*)
139+
- **Application parameters**: path to your Protractor configuration file (e.g.
140+
*protractorConfig.js*)
141+
4. Click OK, place some breakpoints, and start debugging.
142+
143+
144+
## Enabled Control Flow
145+
146+
**Note:** Protractor debugger and element explorer cannot be used for Node.js 8+
147+
148+
**Pausing to Debug**
40149
41150
Protractor supports two methods for pausing to debug - `browser.pause()` and
42151
`browser.debugger()`. You probably want to use `browser.pause()`, unless you
@@ -149,53 +258,7 @@ used from the browser's console.
149258
> window.clientSideScripts.findInputs('username', document.getElementById('#myEl'));
150259
```
151260

152-
**Debugging with the control flow disabled**
153-
154-
If you've set the `SELENIUM_PROMISE_MANAGER` config value to false to [disable the control flow](https://github.com/angular/protractor/blob/master/docs/control-flow.md),
155-
the above methods will not work. Instead, you can now use native `debugger` statements to pause your code. However, you
156-
will need to start your tests using Node's `--inspect-brk` option:
157-
158-
```
159-
node --inspect-brk node_modules/.bin/protractor <config_file>
160-
```
161-
162-
You will then be able to use the Chrome devtools at chrome://inspect to connect to the tests.
163-
164-
165-
Setting Up VSCode for Debugging
166-
-------------------------------
167-
VS Code has built-in [debugging](https://code.visualstudio.com/docs/editor/debugging) support for the Node.js runtime and can debug JavaScript, TypeScript, and any other language that gets transpiled to JavaScript.
168-
169-
To set up VSCode for Protractor, follow the below steps:
170-
171-
1. Click on the Debugging icon in the View Bar on the side of VS Code.
172-
2. Click on the Configure gear icon on the Debug view top bar and choose nodejs environment.
173-
3. It will generate a `launch.json` file under your workspace's `.vscode` folder.
174-
4. Setup your launch.json file by configuring below two commands:
175-
```
176-
"program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
177-
"args": ["${workspaceRoot}/protractorConfig.js"],
178-
```
179-
5. Save your launch.json, put some breakpoints and start debugging.
180-
181-
Setting Up WebStorm for Debugging
182-
---------------------------------
183-
184-
To set up WebStorm for Protractor, do the following:
185-
186-
1. Open the Run/Debug Configurations dialog
187-
2. Add new Node.js configuration.
188-
3. On the Configuration tab set:
189-
- **Node Interpreter**: path to node executable
190-
- **Working directory**: your project base path
191-
- **JavaScript file**: path to Protractor cli.js file (e.g. *node_modules\protractor\built\cli.js*)
192-
- **Application parameters**: path to your Protractor configuration file (e.g.
193-
*protractorConfig.js*)
194-
4. Click OK, place some breakpoints, and start debugging.
195-
196-
197-
Testing Out Protractor Interactively
198-
------------------------------------
261+
**Testing Out Protractor Interactively**
199262

200263
When debugging or first writing test suites, you may find it helpful to
201264
try out Protractor commands without starting up the entire test suite. You can
@@ -222,8 +285,8 @@ matching a locator.
222285

223286
Element explorer will start chrome by default. However, you can specify
224287
another browser, change browser settings, or specify any other config that you
225-
normally would with your protractor test. To do this, pass configs to
226-
protractor like you normally would,
288+
normally would with your protractor test. To do this, pass configs to
289+
protractor like you normally would,
227290
but with the `--elementExplorer` flag set:
228291

229292
protractor [configFile] [options] --elementExplorer
@@ -232,16 +295,15 @@ For example, to connect to ChromeDriver directly, use
232295

233296
protractor --directConnect --elementExplorer
234297

235-
Element explore will ignore your specs, not set up your framework (e.g. jasmine,
298+
Element explore will ignore your specs, not set up your framework (e.g. jasmine,
236299
mocha, cucumber), and only allow you to pass in 1 capability, but will honor
237300
every other parameter in your config.
238301

239-
Note `baseUrl` is used here as the initial page, i.e. element explorer will try
302+
Note `baseUrl` is used here as the initial page, i.e. element explorer will try
240303
to navigate to `baseUrl` automatically on start.
241304

242305

243-
Taking Screenshots
244-
------------------
306+
## Taking Screenshots
245307

246308
WebDriver can snap a screenshot with `browser.takeScreenshot()`. This can be a
247309
good way to help debug tests, especially for tests that run on a continuous integration

docs/firstBreak.png

83.4 KB
Loading

docs/inspector.png

39.8 KB
Loading

0 commit comments

Comments
 (0)