# Cypress HTML-Validate plugin

Validates HTML using [`html-validate`](https://html-validate.org).
It automatically fetches the active source markup from the browser and validates, failing the test if any validation errors is encountered.

## Prerequisites

- NodeJS 14.17 or later.
- `html-validate@2.17` or later.
- `cypress@7.0.1` or later.

## Installation

    npm install --save-dev html-validate cypress-html-validate

Make sure you install both `html-validate` and the plugin `cypress-html-validate`.
With NPM 7 or later it will be satisfied by the peer dependency but for a more consistent and deterministic experience it is suggested to include both as dependencies for your project.

## Usage

### With Cypress 10 or later

Import the plugin:

```ts
import htmlvalidate from "cypress-html-validate/plugin";
```

Add the `setupNodeEvents` if it doesnt already exist (either in the `e2e` or `component` block):

```ts
export default defineConfig({
  e2e: {
    setupNodeEvents(on) {
      htmlvalidate.install(on);
    },
  },
});
```

Import the command in the support file (default `cypress/support/e2e.[jt]s` for E2E-tests and `cypress/support/component.[jt]s` for component tests):

```ts
import "cypress-html-validate/commands";
```

### With earlier versions (pre v10)

Install the plugin in `cypress/plugins/index.js`:

```js
const htmlvalidate = require("cypress-html-validate/plugin");

module.exports = (on) => {
  htmlvalidate.install(on);
};
```

Import the command in the support file `cypress/support/index.js`:

```js
import "cypress-html-validate/commands";
```

### In test files:

```js
it("should be valid", () => {
  cy.visit("/my-page.html");
  cy.htmlvalidate();
});
```

To automatically run after each test you can use `afterEach` either in the spec file or in `cypress/support/index.js`:

```js
afterEach(() => {
  cy.htmlvalidate();
});
```

Options may optionally be passed (both plugin options and html-validate configuration):

```js
/* plugin option to exclude an element */
cy.htmlvalidate({
  exclude: [".ignore-me"],
});

/* html-validate config to disable a rule */
cy.htmlvalidate({
  rules: {
    "input-missing-label": "off",
  },
});

/* both options */
cy.htmlvalidate(
  {
    rules: {
      "input-missing-label": "off",
    },
  },
  {
    exclude: [".ignore-me"],
  },
);
```

Running without a subject validates the entire document (with exception of using configuration options `include` and `exclude`).
If you use it on a subject only that element and its descendants are validated:

```js
it("should be valid", () => {
  cy.visit("/my-page.html");
  cy.get("#my-fancy-element").htmlvalidate();
});
```

## Configuration

`html-validate` and the plugin can configured globally in the `install` function:

```js
/* html-validate configuration */
const config = {
  rules: {
    foo: "error",
  },
};

/* plugin options */
const options = {
  exclude: [],
  include: [],
  formatter(messages) {
    console.log(messages);
  },
};

htmlvalidate.install(on, config, options);
```

The default configuration extends `html-validate:recommended` and `html-validate:document` (see [presets](https://html-validate.org/rules/presets.html)).
This can be overridden by explictly specifying `extends: []`:

```js
htmlvalidate.install(on, {
  extends: [],
});
```

See html-validate documentation for [full description of configuration](https://html-validate.org/usage/index.html#configuration).

If you want to override per call you can pass configuration and/or options directly to the function:

```js
cy.htmlvalidate([config], [options]);
```

## Options

### `exclude: string[]`

A list of selectors to ignore errors from.
Any errors from the elements or any descendant will be ignored.

### `include: []`

A list of selectors to include errors from.
If this is set to non-empty array only errors from elements or any descendants will be included.

### `formatter`

- type: `(messages: Message[]): void`

Custom formatter/reporter for detected errors.
Default uses `console.table(..)` to log to console.
Set to `null` to disable.

The original formatter can be imported with:

```ts
import { formatter } from "cypress-html-validate";
```
