diff --git a/docs/api/index.md b/docs/api/index.md index 2b8043a42..2cc8c3b3c 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -1378,10 +1378,14 @@ test('getComponent', () => { Returns the HTML of an element. +By default the output is formatted with [`js-beautify`](https://github.com/beautify-web/js-beautify) +to make snapshots more readable. Use `raw: true` option to receive the unformatted html string. + **Signature:** ```ts html(): string +html(options?: { raw?: boolean }): string ``` **Details:** @@ -1405,7 +1409,13 @@ import Component from './Component.vue' test('html', () => { const wrapper = mount(Component) - expect(wrapper.html()).toBe('

Hello world

') + expect(wrapper.html()).toBe( + '
\n' + + '

Hello world

\n' + + '
' + ) + + expect(wrapper.html({ raw: true })).toBe('

Hello world

') }) ``` diff --git a/package.json b/package.json index af6756175..3c57115d2 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "@rollup/plugin-node-resolve": "15.0.0", "@rollup/plugin-replace": "5.0.0", "@rollup/plugin-typescript": "9.0.1", + "@types/js-beautify": "1.13.3", "@types/node": "18.0.6", - "@types/pretty": "2.0.1", "@typescript-eslint/eslint-plugin": "5.40.1", "@typescript-eslint/parser": "5.40.1", "@vitejs/plugin-vue": "3.1.2", @@ -43,11 +43,11 @@ "eslint-config-prettier": "8.5.0", "eslint-plugin-prettier": "4.2.1", "husky": "8.0.1", + "js-beautify": "1.14.6", "jsdom": "20.0.1", "jsdom-global": "3.0.2", "lint-staged": "13.0.3", "prettier": "2.7.1", - "pretty": "2.0.0", "reflect-metadata": "0.1.13", "rollup": "3.2.3", "tslib": "2.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24cefa2c7..e5e921bab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,8 +6,8 @@ specifiers: '@rollup/plugin-node-resolve': 15.0.0 '@rollup/plugin-replace': 5.0.0 '@rollup/plugin-typescript': 9.0.1 + '@types/js-beautify': 1.13.3 '@types/node': 18.0.6 - '@types/pretty': 2.0.1 '@typescript-eslint/eslint-plugin': 5.40.1 '@typescript-eslint/parser': 5.40.1 '@vitejs/plugin-vue': 3.1.2 @@ -22,11 +22,11 @@ specifiers: eslint-config-prettier: 8.5.0 eslint-plugin-prettier: 4.2.1 husky: 8.0.1 + js-beautify: 1.14.6 jsdom: 20.0.1 jsdom-global: 3.0.2 lint-staged: 13.0.3 prettier: 2.7.1 - pretty: 2.0.0 reflect-metadata: 0.1.13 rollup: 3.2.3 tslib: 2.4.0 @@ -47,8 +47,8 @@ devDependencies: '@rollup/plugin-node-resolve': 15.0.0_rollup@3.2.3 '@rollup/plugin-replace': 5.0.0_rollup@3.2.3 '@rollup/plugin-typescript': 9.0.1_bvn3ed5hy3sfde644tygjdj4ia + '@types/js-beautify': 1.13.3 '@types/node': 18.0.6 - '@types/pretty': 2.0.1 '@typescript-eslint/eslint-plugin': 5.40.1_ukgdydjtebaxmxfqp5v5ulh64y '@typescript-eslint/parser': 5.40.1_z4bbprzjrhnsfa24uvmcbu7f5q '@vitejs/plugin-vue': 3.1.2_vite@3.1.8+vue@3.2.41 @@ -63,11 +63,11 @@ devDependencies: eslint-config-prettier: 8.5.0_eslint@8.25.0 eslint-plugin-prettier: 4.2.1_hvbqyfstm4urdpm6ffpwfka4e4 husky: 8.0.1 + js-beautify: 1.14.6 jsdom: 20.0.1 jsdom-global: 3.0.2_jsdom@20.0.1 lint-staged: 13.0.3 prettier: 2.7.1 - pretty: 2.0.0 reflect-metadata: 0.1.13 rollup: 3.2.3 tslib: 2.4.0 @@ -782,6 +782,10 @@ packages: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true + /@types/js-beautify/1.13.3: + resolution: {integrity: sha512-ucIPw5gmNyvRKi6mpeojlqp+T+6ZBJeU+kqMDnIEDlijEU4QhLTon90sZ3cz9HZr+QTwXILjNsMZImzA7+zuJA==} + dev: true + /@types/json-schema/7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true @@ -790,10 +794,6 @@ packages: resolution: {integrity: sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==} dev: true - /@types/pretty/2.0.1: - resolution: {integrity: sha512-l18spTC0Q2OEUIHGPyw37XBOacFI4Kng1fgfFjgDTg2FR9wqJ/NY9zWyXv87NRUlFDU6JA+E/GVnNJiWgyon6A==} - dev: true - /@types/resolve/1.20.2: resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} dev: true @@ -1503,15 +1503,6 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true - /condense-newlines/0.2.1: - resolution: {integrity: sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-whitespace: 0.3.0 - kind-of: 3.2.2 - dev: true - /config-chain/1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} dependencies: @@ -2273,13 +2264,6 @@ packages: strip-final-newline: 3.0.0 dev: true - /extend-shallow/2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -2585,10 +2569,6 @@ packages: binary-extensions: 2.2.0 dev: true - /is-buffer/1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true - /is-builtin-module/3.2.0: resolution: {integrity: sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==} engines: {node: '>=6'} @@ -2602,11 +2582,6 @@ packages: has: 1.0.3 dev: true - /is-extendable/0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: true - /is-extglob/2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2653,11 +2628,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /is-whitespace/0.3.0: - resolution: {integrity: sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==} - engines: {node: '>=0.10.0'} - dev: true - /isexe/2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -2684,15 +2654,15 @@ packages: istanbul-lib-report: 3.0.0 dev: true - /js-beautify/1.14.4: - resolution: {integrity: sha512-+b4A9c3glceZEmxyIbxDOYB0ZJdReLvyU1077RqKsO4dZx9FUHjTOJn8VHwpg33QoucIykOiYbh7MfqBOghnrA==} + /js-beautify/1.14.6: + resolution: {integrity: sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==} engines: {node: '>=10'} hasBin: true dependencies: config-chain: 1.1.13 editorconfig: 0.15.3 - glob: 7.2.3 - nopt: 5.0.0 + glob: 8.0.3 + nopt: 6.0.0 dev: true /js-sdsl/4.1.4: @@ -2779,13 +2749,6 @@ packages: hasBin: true dev: true - /kind-of/3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - /levn/0.3.0: resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} engines: {node: '>= 0.8.0'} @@ -2989,9 +2952,9 @@ packages: resolution: {integrity: sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==} dev: true - /nopt/5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} + /nopt/6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} hasBin: true dependencies: abbrev: 1.1.1 @@ -3179,15 +3142,6 @@ packages: hasBin: true dev: true - /pretty/2.0.0: - resolution: {integrity: sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU=} - engines: {node: '>=0.10.0'} - dependencies: - condense-newlines: 0.2.1 - extend-shallow: 2.0.1 - js-beautify: 1.14.4 - dev: true - /prismjs/1.28.0: resolution: {integrity: sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==} engines: {node: '>=6'} diff --git a/src/baseWrapper.ts b/src/baseWrapper.ts index 03150e34e..e28c191a5 100644 --- a/src/baseWrapper.ts +++ b/src/baseWrapper.ts @@ -29,7 +29,7 @@ import { isElement } from './utils/isElement' import type { DOMWrapper } from './domWrapper' import { createDOMWrapper, createVueWrapper } from './wrapperFactory' import { stringifyNode } from './utils/stringifyNode' -import pretty from 'pretty' +import beautify from 'js-beautify' export default abstract class BaseWrapper implements WrapperLike @@ -216,9 +216,19 @@ export default abstract class BaseWrapper ) } abstract setValue(value?: any): Promise - html(): string { - return this.getRootNodes() - .map((node) => pretty(stringifyNode(node))) + + html(options?: { raw?: boolean }): string { + const stringNodes = this.getRootNodes().map((node) => stringifyNode(node)) + if (options?.raw) return stringNodes.join('') + + return stringNodes + .map((node) => + beautify.html(node, { + unformatted: ['code', 'pre', 'em', 'strong', 'span'], + indent_inner_html: true, + indent_size: 2 + }) + ) .join('\n') } diff --git a/src/vueWrapper.ts b/src/vueWrapper.ts index 01ce15ef6..915daf769 100644 --- a/src/vueWrapper.ts +++ b/src/vueWrapper.ts @@ -4,8 +4,6 @@ import { ComponentCustomProperties, ComponentPublicInstance } from 'vue' -// @ts-ignore todo - No DefinitelyTyped package exists for this -import pretty from 'pretty' import { config } from './config' import domEvents from './constants/dom-events' diff --git a/tests/html.spec.ts b/tests/html.spec.ts index d90873f73..d914c8bbc 100644 --- a/tests/html.spec.ts +++ b/tests/html.spec.ts @@ -3,6 +3,12 @@ import { defineComponent, h } from 'vue' import { mount } from '../src' +const nestedTemplate = + '
Text 1
Text 2
' +const NestedNodes = defineComponent({ + template: nestedTemplate +}) + describe('html', () => { it('returns html when mounting single root node', () => { const Component = defineComponent({ @@ -16,6 +22,29 @@ describe('html', () => { expect(wrapper.html()).toBe('
Text content
') }) + it('returns formatted html string', () => { + const wrapper = mount(NestedNodes) + + expect(wrapper.html()).toBe( + '
\n' + + '
Text 1
\n' + + '
Text 2
\n' + + '
' + ) + expect(wrapper.html()).toBe( + '
\n' + + '
Text 1
\n' + + '
Text 2
\n' + + '
' + ) + }) + + it('returns raw html string', () => { + const wrapper = mount(NestedNodes) + + expect(wrapper.html({ raw: true })).toBe(nestedTemplate) + }) + describe('multiple root components', () => { const originalTemplate = [ '
foo
', @@ -35,6 +64,11 @@ describe('html', () => { expect(wrapper.html()).toBe(originalTemplate.join('\n')) }) + it('returns the raw html when mounting multiple root nodes', () => { + const wrapper = mount(Component) + expect(wrapper.html({ raw: true })).toBe(originalTemplate.join('')) + }) + it('returns the html when multiple root component is located inside other component', () => { const ParentComponent = defineComponent({ components: { MultipleRoots: Component },