Skip to content

Commit

Permalink
feat: implement REPL interface to debug tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DudaGod committed Dec 27, 2023
1 parent a577d21 commit 4f230b7
Show file tree
Hide file tree
Showing 27 changed files with 977 additions and 637 deletions.
125 changes: 113 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,9 @@ shows the following
--update-refs update screenshot references or gather them if they do not exist ("assertView" command)
--inspect [inspect] nodejs inspector on [=[host:]port]
--inspect-brk [inspect-brk] nodejs inspector with break at the start
--repl [type] run one test, call `browser.switchToRepl` in test code to open repl interface (default: false)
--repl-before-test [type] open repl interface before test run (default: false)
--repl-on-fail [type] open repl interface on test fail only (default: false)
-h, --help output usage information
```

Expand Down Expand Up @@ -1549,6 +1552,116 @@ hermione_base_url=http://example.com hermione path/to/mytest.js
hermione_browsers_firefox_sessions_per_browser=7 hermione path/to/mytest.js
```

### Debug mode

In order to understand what is going on in the test step by step, there is a debug mode. You can run tests in this mode using these options: `--inspect` and `--inspect-brk`. The difference between them is that the second one stops before executing the code.

Example:
```
hermione path/to/mytest.js --inspect
```

**Note**: In the debugging mode, only one worker is started and all tests are performed only in it.
Use this mode with option `sessionsPerBrowser=1` in order to debug tests one at a time.

### REPL mode

Hermione provides a [REPL](https://en.wikipedia.org/wiki/Read–eval–print_loop) implementation that helps you not only to learn the framework API, but also to debug and inspect your tests. In this mode, there is no timeout for the duration of the test (it means that there will be enough time to debug the test). It can be used by specifying the CLI options:

- `--repl` - in this mode, only one test in one browser should be run, otherwise an error is thrown. REPL interface does not start automatically, so you need to call [switchToRepl](#switchtorepl) command in the test code. Disabled by default;
- `--repl-before-test` - the same as `--repl` option except that REPL interface opens automatically before run test. Disabled by default;
- `--repl-on-fail` - the same as `--repl` option except that REPL interface opens automatically on test fail. Disabled by default.

#### switchToRepl

Browser command that stops the test execution and opens REPL interface in order to communicate with browser. For example:

```js
it('foo', async ({browser}) => {
console.log('before open repl');

await browser.switchToRepl();

console.log('after open repl');
});
```

And run it using the command:

```bash
npx hermione --repl --grep "foo" -b "chrome"
```

In this case, we are running only one test in one browser (or you can use `hermione.only.in('chrome')` before `it` + `it.only`).
When executing the test, the text `before open repl` will be displayed in the console first, then test execution stops, REPL interface is opened and waits your commands. So we can write some command in the terminal:

```js
await browser.getUrl();
// about:blank
```

In the case when you need to execute a block of code, for example:

```js
for (const item of [...Array(3).keys]) {
await browser.$(`.selector_${item}`).isDisplayed();
}
```

you need to switch to editor mode by running the `.editor` command in REPL and insert the desired a block of code. Then execute it by pressing `Ctrl+D`.
it is worth considering that some of code can be executed without editor mode:
- one-line code like `await browser.getUrl().then(console.log)`;
- few lines of code without using block scope or chaining, for example:
```js
await browser.url('http://localhost:3000');
await browser.getUrl();
// http://localhost:3000
```

After user closes the server, the test will continue to run (text `after open repl` will be displayed in the console and browser will close).

Another command features:
- all `const` and `let` declarations called in REPL mode are modified to `var` in runtime. This is done in order to be able to redefine created variables;
- before switching to the REPL mode `process.cwd` is replaced with the path to the folder of the executed test. After exiting from the REPL mode `process.cwd` is restored. This feature allows you to import modules relative to the test correctly;
- ability to pass the context to the REPL interface. For example:

```js
it('foo', async ({browser}) => {
const foo = 1;
await browser.switchToRepl({foo});
});
```

And now `foo` variable is available in REPL:

```bash
console.log("foo:", foo);
// foo: 1
```



#### Test development in runtime

For quick test development without restarting the test or the browser, you can run the test in the terminal of IDE with enabled REPL mode:

```bash
npx hermione --repl-before-test --grep "foo" -b "chrome"
```

After that, you need to configure the hotkey in IDE to run the selected one or more lines of code in the terminal. As a result, each new written line can be sent to the terminal using a hotkey and due to this, you can write a test much faster.

##### How to set up using VSCode

1. Open `Code` -> `Settings...` -> `Keyboard Shortcuts` and print `run selected text` to search input. After that, you can specify the desired key combination
2. Run hermione in repl mode (examples were above)
3. Select one or mode lines of code and press created hotkey

##### How to set up using Webstorm

Ability to run selected text in terminal will be available after this [issue](https://youtrack.jetbrains.com/issue/WEB-49916/Debug-JS-file-selection) will be resolved.

### Environment variables

#### HERMIONE_SKIP_BROWSERS
Expand All @@ -1568,18 +1681,6 @@ For example,
HERMIONE_SETS=desktop,touch hermione
```

### Debug mode

In order to understand what is going on in the test step by step, there is a debug mode. You can run tests in this mode using these options: --inspect and --inspect-brk. The difference between them is that the second one stops before executing the code.

Example:
```
hermione path/to/mytest.js --inspect
```

**Note**: In the debugging mode, only one worker is started and all tests are performed only in it.
Use this mode with option `sessionsPerBrowser=1` in order to debug tests one at a time.

## Programmatic API

With the API, you can use Hermione programmatically in your scripts or build tools. To do this, you must require `hermione` module and create instance:
Expand Down
Loading

0 comments on commit 4f230b7

Please sign in to comment.