Skip to content

Commit

Permalink
Merge pull request #6 from crutchcorn/alpha-docs
Browse files Browse the repository at this point in the history
Initial docs for the project
  • Loading branch information
crutchcorn committed Dec 14, 2021
2 parents 74c8f5c + 544e8db commit d557c14
Show file tree
Hide file tree
Showing 16 changed files with 1,077 additions and 77 deletions.
218 changes: 218 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
# API

`CLI Testing Library`, despite taking clear inspiration from, does not re-export
anything from
[`DOM Testing Library`](https://testing-library.com/docs/dom-testing-library/).
Likewise, while we've done our best to match the API names of
[Testing Library's Core API](https://testing-library.com/docs/), because of the
inherent differences between CLI apps and web apps, we're unable to match all of
them.

> Know of a Testing Library Core API that you think would fit here that isn't
> present?
> [Let us know!](https://github.com/crutchcorn/cli-testing-library/issues)
Instead, the following API is what `CLI Testing Library` provides the following.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [`render`](#render)
- [`render` Options](#render-options)
- [`cwd`](#cwd)
- [`spawnOpts`](#spawnopts)
- [`render` Result](#render-result)
- [`...queries`](#queries)
- [ByText](#bytext)
- [`userEvent[eventName]`](#usereventeventname)
- [`debug`](#debug)
- [`hasExit`](#hasexit)
- [`process`](#process)
- [`stdoutArr`/`stderrArr`](#stdoutarrstderrarr)
- [`clear`](#clear)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# `render`

```typescript
function render(
command: string,
args: string[],
options?: {
/* You won't often use this, expand below for docs on options */
},
): RenderResult
```

Run the CLI application in a newly spawned process.

```javascript
import {render} from 'cli-testing-library'
render('node', ['./path/to/script.js'])
```

```javascript
import {render} from 'cli-testing-library'
test('renders a message', () => {
const {getByText} = render('node', ['./console-out.js'])
expect(getByText('Hello, world!')).toBeTruthy()
})
```

# `render` Options

You won't often need to specify options, but if you ever do, here are the
available options which you could provide as a third argument to `render`.

## `cwd`

By default, `CLI Testing Library` will run the new process in the working
directory of your project's root, as defined by your testing framework. If you
provide your own working directory via this option, it will change the execution
directory of your process.

For example: If you are end-to-end testing a file moving script, you don't want
to have to specify the absolute path every time. In this case, you can specify a
directory as the render `cwd`.

```javascript
const containingPath = path.resolve(__dirname, './movables')
const {getByText} = render('node', ['mover.js'], {
cwd: containingPath,
})
```

## `spawnOpts`

Oftentimes, you want to modify the behavior of the spawn environment. This may
include things like changing the shell that's used to run scripts or more.

This argument allows you to configure the options that are passed to the
underlying
[`child_process.spawn` NodeJS API](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options).

```javascript
const {getByText} = render('script.ps1', {
spawnOpts: {
shell: 'powershell.exe',
},
})
```

# `render` Result

The `render` method returns an object that has a few properties:

## `...queries`

The most important feature of render is that the queries from
[CLI Testing Library](https://github.com/crutchcorn/cli-testing-library) are
automatically returned with their first argument bound to the testInstance.

See [Queries](./queries.md) to learn more about how to use these queries and the
philosophy behind them.

### ByText

> getByText, queryByText, findByText

```typescript
getByText(
// If you're using `screen`, then skip the container argument:
instance: TestInstance,
text: TextMatch,
options?: {
exact?: boolean = true,
trim?: boolean = false,
stripAnsi?: boolean = false,
collapseWhitespace?: boolean = false,
normalizer?: NormalizerFn,
suggest?: boolean,
}): TestInstance
```

Queries for test instance `stdout` results with the given text (and it also
accepts a TextMatch).

These options are all standard for text matching. To learn more, see our
[Queries page](./queries.md).

## `userEvent[eventName]`

```javascript
userEvent[eventName](...eventProps)
```

> While `userEvent` isn't usually returned on `render` in, say,
> `React Testing Library`, we're able to do so because of our differences in
> implementation with upstream. See our [Differences](./differences.md) doc for
> more.

This object is the same as described with
[`userEvent` documentation](./user-event.md) with the key difference that
`instance` is not expected to be passed when bound to `render`.

## `debug`

This method is a shortcut for `console.log(prettyCLI(instance)).`

```javascript
import {render} from 'cli-testing-library'
const {debug} = render('command')
debug()
// Hello, world! How are you?
//
// you can also pass an instance: debug(getByText('message'))
// and you can pass all the same arguments to debug as you can
// to prettyCLI:
// const maxLengthToPrint = 10000
// debug(getByText('message'), maxLengthToPrint)
```

This is a simple wrapper around `prettyCLI` which is also exposed and comes from
[CLI Testing Library](./debug.md).

## `hasExit`

This method allows you to check if the spawned process has exit, and if so, what
exit code it closed with.

```javascript
const instance = render('command')
await waitFor(() => instance.hasExit()).toMatchObject({exitCode: 1})
```

This method returns `null` if still running, but `{exitCode: number}` if it has
exit

## `process`

The spawned process created by your rendered `TestInstnace`. It's a
`child_instance`. This is a
[regularly spawned process](https://nodejs.org/api/child_process.html#child_processspawncommand-args-options),
so you can call `process.pid` etc. to inspect the process.

## `stdoutArr`/`stderrArr`

Each of these is an array of what's output by their respective `std`\* pipe.
This is used internally to create the [`debug`methods](./debug.md) and more.
They're defined as:

```typescript
interface TestInstance {
stdoutArr: Array<Buffer | string>
stderrArr: Array<Buffer | string>
}
```

## `clear`

This method acts as the terminal `clear` command might on most systems. It
allows you to clear out the buffers for `stdoutArr` and `stderrArr` - even in
the middle of processing - in order to do more narrowed queries.
56 changes: 56 additions & 0 deletions docs/configure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Configuration Options

## Introduction

The library can be configured via the `configure` function, which accepts:

- a plain JS object; this will be merged into the existing configuration. e.g.
`configure({asyncUtilTimeout: 800})`
- a function; the function will be given the existing configuration, and should
return a plain JS object which will be merged as above, e.g.
`configure(existingConfig => ({something: [...existingConfig.something, 'extra value for the something array']}))`

## Options

### `showOriginalStackTrace`

By default, `waitFor` will ensure that the stack trace for errors thrown by
Testing Library is cleaned up and shortened so it's easier for you to identify
the part of your code that resulted in the error (async stack traces are hard to
debug). If you want to disable this, then set`showOriginalStackTrace` to
`false`. You can also disable this for a specific call in the options you pass
to `waitFor`.

### `throwSuggestions` (experimental)

When enabled, if [better queries](./queries.md) are available the
test will fail and provide a suggested query to use instead. Default to `false`.

To disable a suggestion for a single query just add `{suggest:false}` as an
option.

```js
getByText('foo', {suggest: false}) // will not throw a suggestion
```

### `getInstanceError`

A function that returns the error used when
[get or find queries](./queries.md#types-of-queries) fail. Takes the error
message and `TestInstance` object as arguments.

### `asyncUtilTimeout`

The global timeout value in milliseconds used by `waitFor` utilities. Defaults
to 1000ms.

### `renderAwaitTime`

By default, we wait for the CLI to `spawn` the command from `render`. If we immediately resolve
the promise to allow users to query, however, we lose the ability to `getByText` immediately after rendering.
This [differs greatly from upstream Testing Library](./differences.md) and makes for a poor testing experience.

As a result, we wait this duration before resolving the promise after the process is spawned. This gives runtimes like
NodeJS time to spin up and execute commands.

Defaults to 100ms.
56 changes: 56 additions & 0 deletions docs/debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Debug

## Automatic Logging

When you use any `get` calls in your test cases, the current state of the
`testInstance` (CLI) gets printed on the console. For example:

```javascript
// Hello world
getByText(container, 'Goodbye world') // will fail by throwing error
```

The above test case will fail, however it prints the state of your DOM under
test, so you will get to see:

```
Unable to find an element with the text: Goodbye world. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
Here is the state of your container:
Hello world
```

Note: Since the CLI size can get really large, you can set the limit of CLI
content to be printed via environment variable `DEBUG_PRINT_LIMIT`. The default
value is `7000`. You will see `...` in the console, when the CLI content is
stripped off, because of the length you have set or due to default size limit.
Here's how you might increase this limit when running tests:

```
DEBUG_PRINT_LIMIT=10000 npm test
```

This works on macOS/Linux, you'll need to do something else for Windows. If
you'd like a solution that works for both, see
[`cross-env`](https://www.npmjs.com/package/cross-env).

## `prettyCLI`

Built on top of [`strip-ansi`](https://github.com/chalk/strip-ansi) this helper
function can be used to print out readable representation of the CLI `stdout` of
a process. This can be helpful for instance when debugging tests.

It is defined as:

```typescript
function prettyDOM(instance: TestInstance, maxLength?: number): string
```

It receives the `TestInstance` to print out, an optional extra parameter to
limit the size of the resulting string, for cases when it becomes too large.

This function is usually used alongside `console.log` to temporarily print out
CLI outputs during tests for debugging purposes:

This function is what also powers
[the automatic debugging output described above](#debugging).
Loading

0 comments on commit d557c14

Please sign in to comment.