{"_id":"@capitalg/preact-testing-library","_rev":"1-adecaeccf702d4911cebb6dfe84fb41a","name":"@capitalg/preact-testing-library","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@capitalg/preact-testing-library","version":"1.0.0","description":"Simple and complete Preact DOM testing utilities that encourage good testing practices.","main":"dist/index.js","typings":"typings/index.d.ts","engines":{"node":">=8"},"scripts":{"add-contributor":"kcd-scripts contributors add","build":"kcd-scripts build","lint":"kcd-scripts lint","test":"kcd-scripts test","test:update":"npm test -- --updateSnapshot --coverage","validate":"kcd-scripts validate","setup":"npm install && npm run validate -s","precommit":"kcd-scripts precommit","semantic-release":"semantic-release","travis-deploy-once":"travis-deploy-once"},"keywords":["testing","preact","ui","dom","jsdom","unit","integration","functional","end-to-end","e2e"],"author":{"name":"Anto Aravinth"},"license":"MIT","dependencies":{"@babel/runtime":"^7.1.5","@testing-library/dom":"^5.2.0","babel-plugin-module-resolver":"^2.7.1","jest-dom":"^2.1.0","wait-for-expect":"0.4.0"},"devDependencies":{"@babel/core":"^7.1.2","@babel/plugin-proposal-class-properties":"^7.1.0","@babel/plugin-proposal-object-rest-spread":"^7.0.0","@babel/plugin-transform-react-jsx":"^7.0.0","@babel/preset-env":"^7.1.0","axios":"^0.18.0","babel-core":"^7.0.0-bridge.0","babel-jest":"^23.6.0","eslint-config-standard":"^12.0.0","eslint-config-standard-preact":"^1.1.6","eslint-plugin-import":"^2.14.0","eslint-plugin-jest":"^21.26.2","eslint-plugin-node":"^8.0.0","eslint-plugin-promise":"^4.0.1","eslint-plugin-react":"^7.11.1","eslint-plugin-standard":"^4.0.0","history":"^4.7.2","jest-in-case":"^1.0.2","jsdom":"11.11.0","kcd-scripts":"^0.45.0","preact":"^8.2.7","preact-redux":"^2.0.3","redux":"^3.7.2","semantic-release":"^15.5.1","travis-deploy-once":"^5.0.0"},"eslintConfig":{"extends":["standard","standard-preact"],"plugins":["jest"],"env":{"jest/globals":true},"rules":{"import/named":"off","import/no-unassigned-import":"off","react/react-in-jsx-scope":"off","react/prefer-stateless-function":"off","react/prop-types":"off","no-empty-pattern":"off","space-before-function-paren":"off","comma-dangle":"off","object-curly-spacing":"off","jsx-quotes":"off","spaced-comment":"off"}},"eslintIgnore":["node_modules","coverage","dist"],"jest":{"transform":{"^.+\\.jsx?$":"babel-jest"},"testEnvironment":"jsdom","moduleFileExtensions":["js","jsx"]},"repository":{"type":"git","url":"git+https://github.com/capitalg/preact-testing-library.git"},"bugs":{"url":"https://github.com/capitalg/preact-testing-library/issues"},"homepage":"https://github.com/capitalg/preact-testing-library#readme","gitHead":"592a414093849b7528702e8fcbafab8fe89dd417","_id":"@capitalg/preact-testing-library@1.0.0","_nodeVersion":"11.14.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-vW6P87EqJd5KiKVLOw0jQMOt/5QVhYjWh8WyLJygqS7RLGQCMNroY8jrHtWYVj568GIfBnEjatN4lwoSed2cRA==","shasum":"58be0ee25f304117ec1735d62f947eec0257e2aa","tarball":"https://registry.npmjs.org/@capitalg/preact-testing-library/-/preact-testing-library-1.0.0.tgz","fileCount":16,"unpackedSize":51163,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdAGqYCRA9TVsSAnZWagAATe8P+gJNH1wG9LaVGzmjxcEx\ni1ipUEtjC5K1cq4c72rRmYygKaWV3f67eEdoL3sWuMSpsiFhouWPKhF3XeG8\nU8rd8cst9rwCDgnY+b/Jk/8Ac9uSNacnVk5x9hBGHZ5MX1NwHQ//l9L9iOGu\n2Ld8ZfLi3F1/553Dtg9KTVxUQ7chD+8Bc1z6EF+mp+swHHrO+q0soqtrAZXA\nfkHgaLT/BN5abYMeWfzuapxsBiOaZjq6HXHgJzM1xLYmcZHnpS71MqIqSN0S\nkG4F3EpNT9V9ngYlaRGpUz+r10ny+1JwnvaBgHnffazaz6nxlHv+OTuLPVL0\no6E/wQtXgWXdD9lzS0hBJ7bx/8HxahG+nWMd16Hxem6n/AQLSat/rz+M+nRp\nRVey+7BqhpluCWOJm36QZK4VwpURBAK8w2xVIMHP8y5RH/QhjVXgE2mHarqQ\nKG4KPQoXVKRR1LYsGfhNYc4nDirZ6IZvPrsoT4qSGXeIWpiKaSarZiorneQY\nnE5m0wy7dM1ZOWBDFhD2j+8Ue0ln5/zL8qUcgjNHs0R8nkXGeV1KhGM68P/S\nEtaYosFNgGgz6LczQPzfHO37fb7/t0LzE4L4VXBIb4QAzhBFeMGJIwPHhUKq\nzc93ktwLtBKvBtcUIOyUMpcIuzIIJO0sOiLJcvHkvbkZtM5M59tOEHAyypZR\nJ2OS\r\n=tx/4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAQiu8QVFHaEos/09HWPvdnLshjjKf7bO2eVHghrkg8/AiEAv4FGx9ZEaIVoRaJdloaxScsuR7xeXKIhRfE25IPUlz8="}]},"maintainers":[{"name":"capitalg","email":"gurkaran.poonia@gmail.com"}],"_npmUser":{"name":"capitalg","email":"gurkaran.poonia@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/preact-testing-library_1.0.0_1560308375487_0.15339093936701542"},"_hasShrinkwrap":false}},"time":{"created":"2019-06-12T02:59:35.447Z","1.0.0":"2019-06-12T02:59:35.634Z","modified":"2022-04-04T21:45:59.439Z"},"maintainers":[{"name":"capitalg","email":"gurkaran.poonia@gmail.com"}],"description":"Simple and complete Preact DOM testing utilities that encourage good testing practices.","homepage":"https://github.com/capitalg/preact-testing-library#readme","keywords":["testing","preact","ui","dom","jsdom","unit","integration","functional","end-to-end","e2e"],"repository":{"type":"git","url":"git+https://github.com/capitalg/preact-testing-library.git"},"author":{"name":"Anto Aravinth"},"bugs":{"url":"https://github.com/capitalg/preact-testing-library/issues"},"license":"MIT","readme":"<div align=\"center\">\n<h1>preact-testing-library</h1>\n\n<p>Simple and complete Preact DOM testing utilities that encourage good testing practices.</p>\n</div>\n\n<hr />\n\n## The problem\n\nYou want to write maintainable tests for your Preact components. As a part of\nthis goal, you want your tests to avoid including implementation details of\nyour components and rather focus on making your tests give you the confidence\nfor which they are intended. As part of this, you want your testbase to be\nmaintainable in the long run so refactors of your components (changes to\nimplementation but not functionality) don't break your tests and slow you and\nyour team down.\n\n## This solution\n\nThe `preact-testing-library` is a very light-weight solution for testing Preact\ncomponents. It provides light utility functions on top of `preact` in a way that encourages better testing practices.\nIt's primary guiding principle is:\n\n> [The more your tests resemble the way your software is used, the more confidence they can give you.][guiding-principle]\n\nSo rather than dealing with instances of rendered Preact components, your tests\nwill work with actual DOM nodes. The utilities this library provides facilitate\nquerying the DOM in the same way the user would. Finding for elements by their\nlabel text (just like a user would), finding links and buttons from their text\n(like a user would). It also exposes a recommended way to find elements by a\n`data-testid` as an \"escape hatch\" for elements where the text content and label\ndo not make sense or is not practical.\n\nThis library encourages your applications to be more accessible and allows you\nto get your tests closer to using your components the way a user will, which\nallows your tests to give you more confidence that your application will work\nwhen a real user uses it.\n\nThis library is a replacement for [enzyme](http://airbnb.io/enzyme/). While you\n_can_ follow these guidelines using enzyme itself, enforcing this is harder\nbecause of all the extra utilities that enzyme provides (utilities which\nfacilitate testing implementation details). Read more about this in\n[the FAQ](#faq) below.\n\n**What this library is not**:\n\n1.  A test runner or framework\n2.  Specific to a testing framework (though we recommend Jest as our\n    preference, the library works with any framework)\n\n> NOTE: This library is built on top of\n> [`dom-testing-library`](https://github.com/kentcdodds/dom-testing-library)\n> which is where most of the logic behind the queries is. Also this is inspired from\n> [`react-testing-library`](https://github.com/kentcdodds/react-testing-library)\n\n## Table of Contents\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [`render`](#render)\n  - [`cleanup`](#cleanup)\n  - [`wait`](#wait)\n  - [`fireEvent(node: HTMLElement, event: Event)`](#fireeventnode-htmlelement-event-event)\n- [`debounceRenderingOff`](#debouncerenderingoff)\n- [`TextMatch`](#textmatch)\n- [`query` APIs](#query-apis)\n- [FAQ](#faq)\n- [Guiding Principles](#guiding-principles)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n## Installation\n\nThis module is distributed via [npm][npm] which is bundled with [node][node] and\nshould be installed as one of your project's `devDependencies`:\n\n```\nnpm install --save-dev preact-testing-library\n```\n\nYou may also be interested in installing `dom-testing-library` so you can use\n[the custom jest matchers](https://github.com/kentcdodds/dom-testing-library/blob/master/README.md#custom-jest-matchers)\n\n## Usage\n\n```javascript\n// __tests__/fetch.js\nimport preact from 'preact'\nimport {render, flushPromises, FireEvent} from '../'\nimport axiosMock from 'axios' // the mock lives in a __mocks__ directory\nimport Fetch from '../fetch' // see the tests for a full implementation\n\ntest('Fetch makes an API call and displays the greeting when load-greeting is clicked', async () => {\n  // Arrange\n  axiosMock.get.mockImplementationOnce(() =>\n    Promise.resolve({\n      data: {greeting: 'hello there'},\n    }),\n  )\n  const url = '/greeting'\n  const {getByText} = render(<Fetch url={url} />)\n\n  // Act\n  FireEvent.fireEvent(getByText('Fetch'), 'click')\n\n  await flushPromises()\n\n  // Assert\n  expect(axiosMock.get).toHaveBeenCalledTimes(1)\n  expect(axiosMock.get).toHaveBeenCalledWith(url)\n  // this assertion is funny because if the textContent were not \"hello there\"\n  // then the `getByText` would throw anyway... 🤔\n  expect(getByText('hello there').textContent).toBe('hello there')\n  // expect(container.firstChild).toMatchSnapshot()\n})\n```\n\n### `render`\n\nRender into a container which is appended to document.body. It should be used with [cleanup](#cleanup):\n\n```javascript\nimport {render, cleanup} from 'preact-testing-library'\n\nafterEach(cleanup)\n\nrender(<div />)\n```\n\nIn the example above, the `render` method returns an object that has a few\nproperties:\n\n#### `container`\n\nThe containing DOM node of your rendered Preact Element (rendered using\n`Preact.render`). It's a `div`. This is a regular DOM node, so you can call\n`container.querySelector` etc. to inspect the children.\n\n> Tip: To get the root element of your rendered element, use `container.firstChild`.\n\n#### `debug`\n\nThis method is a shortcut for `console.log(prettyDOM(container))`.\n\n```javascript\nimport {render} from 'preact-testing-library'\n\nconst HelloWorld = () => <h1>Hello World</h1>\nconst {debug} = render(<HelloWorld />)\ndebug()\n// <div>\n//   <h1>Hello World</h1>\n// </div>\n// you can also pass an element: debug(getByTestId('messages'))\n```\n\nThis is a simple wrapper around prettyDOM which is also exposed and comes from [dom-testing-library](https://github.com/kentcdodds/dom-testing-library/blob/master/README.md#prettydom).\n\n#### `rerender`\n\nIt'd probably be better if you test the component that's doing the prop updating to ensure that the props are being updated correctly (see the Guiding Principles section). That said, if you'd prefer to update the props of a rendered component in your test, this function can be used to update props of the rendered component.\n\n```javascript\nimport {render} from 'preact-testing-library'\n\nconst {rerender} = render(<NumberDisplay number={1} />)\n\n// re-render the same component with different props\nrerender(<NumberDisplay number={2} />)\n```\n\n#### `unmount`\n\nThis will cause the rendered component to be unmounted. This is useful for\ntesting what happens when your component is removed from the page (like testing\nthat you don't leave event handlers hanging around causing memory leaks).\n\n> This method is a pretty small abstraction over\n> `render(ui, document.body, container)`\n\n```javascript\nconst {container, unmount} = render(<Login />)\nunmount()\n// your component has been unmounted and now: container.innerHTML === ''\n```\n\n#### `getByLabelText(text: TextMatch, options: {selector: string = '*'}): HTMLElement`\n\nThis will search for the label that matches the given [`TextMatch`](#textmatch),\nthen find the element associated with that label.\n\n```javascript\nconst inputNode = getByLabelText('Username')\n\n// this would find the input node for the following DOM structures:\n// The \"for\" attribute (NOTE: in JSX with React you'll write \"htmlFor\" rather than \"for\")\n// <label for=\"username-input\">Username</label>\n// <input id=\"username-input\" />\n//\n// The aria-labelledby attribute\n// <label id=\"username-label\">Username</label>\n// <input aria-labelledby=\"username-label\" />\n//\n// Wrapper labels\n// <label>Username <input /></label>\n//\n// It will NOT find the input node for this:\n// <label><span>Username</span> <input /></label>\n//\n// For this case, you can provide a `selector` in the options:\nconst inputNode = getByLabelText('username', {selector: 'input'})\n// and that would work\n// Note that <input aria-label=\"username\" /> will also work, but take\n// care because this is not a label that users can see on the page. So\n// the purpose of your input should be obvious for those users.\n```\n\n> Note: This method will throw an error if it cannot find the node. If you don't\n> want this behavior (for example you wish to assert that it doesn't exist),\n> then use `queryByLabelText` instead.\n\n#### `getByPlaceholderText(text: TextMatch): HTMLElement`\n\nThis will search for all elements with a placeholder attribute and find one\nthat matches the given [`TextMatch`](#textmatch).\n\n```javascript\n// <input placeholder=\"Username\" />\nconst inputNode = getByPlaceholderText('Username')\n```\n\n> NOTE: a placeholder is not a good substitute for a label so you should\n> generally use `getByLabelText` instead.\n\n#### `getByText(text: TextMatch): HTMLElement`\n\nThis will search for all elements that have a text node with `textContent`\nmatching the given [`TextMatch`](#textmatch).\n\n```javascript\n// <a href=\"/about\">About ℹ️</a>\nconst aboutAnchorNode = getByText('about')\n```\n\n#### `getByAltText(text: TextMatch): HTMLElement`\n\nThis will return the element (normally an `<img>`) that has the given `alt`\ntext. Note that it only supports elements which accept an `alt` attribute:\n[`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img),\n[`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input),\nand [`<area>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area)\n(intentionally excluding [`<applet>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/applet) as it's deprecated).\n\n```javascript\n// <img alt=\"Incredibles 2 Poster\" src=\"/incredibles-2.png\" />\nconst incrediblesPosterImg = getByAltText(/incredibles.*poster$/i)\n```\n\n#### `getByTestId(text: TextMatch): HTMLElement`\n\nA shortcut to `` container.querySelector(`[data-testid=\"${yourId}\"]`) `` (and it\nalso accepts a [`TextMatch`](#textmatch)).\n\n```javascript\n// <input data-testid=\"username-input\" />\nconst usernameInputElement = getByTestId('username-input')\n```\n\n> In the spirit of [the guiding principles](#guiding-principles), it is\n> recommended to use this only after `getByLabel`, `getByPlaceholderText` or\n> `getByText` don't work for your use case. Using data-testid attributes do\n> not resemble how your software is used and should be avoided if possible.\n> That said, they are _way_ better than querying based on DOM structure.\n> Learn more about `data-testid`s from the blog post\n> [\"Making your UI tests resilient to change\"][data-testid-blog-post]\n\n### `cleanup`\n\nUnmounts Preact trees that were mounted with [render](#render).\n\n```javascript\nafterEach(cleanup)\n\ntest('renders into document', () => {\n  render(<div>)\n  // ...\n})\n```\n\nFailing to call `cleanup` when you've called `render` could\nresult in a memory leak and tests which are not `idempotent` (which can\nlead to difficult to debug errors in your tests).\n\n### `wait`\n\nDefined as:\n\n```typescript\nfunction wait(\n  callback?: () => void,\n  options?: {\n    timeout?: number\n    interval?: number\n  },\n): Promise<void>\n```\n\nWhen in need to wait for non-deterministic periods of time you can use `wait`,\nto wait for your expectations to pass. The `wait` function is a small wrapper\naround the\n[`wait-for-expect`](https://github.com/TheBrainFamily/wait-for-expect) module.\nHere's a simple example:\n\n```javascript\n// ...\n// wait until the callback does not throw an error. In this case, that means\n// it'll wait until we can get a form control with a label that matches \"username\"\nawait wait(() => getByLabelText('username'))\ngetByLabelText('username').value = 'chucknorris'\n// ...\n```\n\nThis can be useful if you have a unit test that mocks API calls and you need\nto wait for your mock promises to all resolve. This can also be useful when\n(for example) you integration test your apollo-connected Preact components that\ngo a couple level deep, with queries fired up in consequent components.\n\nThe default `callback` is a no-op function (used like `await wait()`). This can\nbe helpful if you only need to wait for one tick of the event loop.\n\nThe default `timeout` is `4500ms` which will keep you under\n[Jest's default timeout of `5000ms`](https://facebook.github.io/jest/docs/en/jest-object.html#jestsettimeouttimeout).\n\nThe default `interval` is `50ms`. However it will run your callback immediately\non the next tick of the event loop (in a `setTimeout`) before starting the\nintervals.\n\n### `fireEvent(node: HTMLElement, event: Event)`\n\nFire DOM events.\n\nYou can fire events directly to your DOM. You can render into the document using the\n[render](#renderintodocument) utility.\n\n```javascript\nimport {cleanup, render, fireEvent} from 'preact-testing-library'\n\n// don't forget to clean up the document.body\nafterEach(cleanup)\n\ntest('clicks submit button', () => {\n  const spy = jest.fn()\n  const {getByText} = render(<button onClick={spy}>Submit</button>)\n\n  fireEvent(\n    getByText('Submit'),\n    new MouseEvent('click', {\n      bubbles: true, // click events must bubble for React to see it\n      cancelable: true,\n    }),\n  )\n\n  expect(spy).toHaveBeenCalledTimes(1)\n})\n```\n\n#### `fireEvent[eventName](node: HTMLElement, eventProperties: Object)`\n\nConvenience methods for firing DOM events. Check out\n[dom-testing-library/src/events.js](https://github.com/kentcdodds/dom-testing-library/blob/master/src/events.js)\nfor a full list as well as default `eventProperties`.\n\n```javascript\n// similar to the above example\n// click will bubble for React to see it\nconst rightClick = {button: 2}\nfireEvent.click(getElementByText('Submit'), rightClick)\n// default `button` property for click events is set to `0` which is a left click.\n```\n\n## `debounceRenderingOff`\n\nPreact `setState` is debounced, which means any call `setState`, you have to use `wait` or `flushPromise`\nAPI to assert. However, there is a handy method for this `debounceRenderingOff`.\n\nYou can invoke this `debounceRenderingOff` to turn off the debounce feature of Preact.\n\n```javascript\ntest('testing different types of events with debounce off', () => {\n  debounceRenderingOff() //turns off the debounce, no need for any waits!\n  const {getByTestId, getByText, queryByText} = render(<MyForm />)\n  const checkBox = getByTestId('checkbox')\n\n  // Act\n  fireEvent.click(checkBox)\n  const textbox = getByTestId('textbox')\n  textbox.value = 'test value'\n  fireEvent.change(textbox)\n\n  // Assert\n  expect(queryByText('No')).not.toBeInTheDOM()\n  expect(getByText('Yes')).toBeInTheDOM()\n  expect(getByText('test value')).toBeInTheDOM()\n})\n```\n\n## `TextMatch`\n\nSeveral APIs accept a `TextMatch` which can be a `string`, `regex` or a\n`function` which returns `true` for a match and `false` for a mismatch.\n\nHere's an example\n\n```javascript\n// <div>Hello World</div>\n// all of the following will find the div\ngetByText('Hello World') // full match\ngetByText('llo worl') // substring match\ngetByText('hello world') // strings ignore case\ngetByText(/Hello W?oRlD/i) // regex\ngetByText((content, element) => content.startsWith('Hello')) // function\n\n// all of the following will NOT find the div\ngetByText('Goodbye World') // non-string match\ngetByText(/hello world/) // case-sensitive regex with different case\n// function looking for a span when it's actually a div\ngetByText((content, element) => {\n  return element.tagName.toLowerCase() === 'span' && content.startsWith('Hello')\n})\n```\n\n## `query` APIs\n\nEach of the `get` APIs listed in [the `render`](#render) section above have a\ncomplimentary `query` API. The `get` APIs will throw errors if a proper node\ncannot be found. This is normally the desired effect. However, if you want to\nmake an assertion that an element is _not_ present in the DOM, then you can use\nthe `query` API instead:\n\n```javascript\nconst submitButton = queryByText('submit')\nexpect(submitButton).toBeNull() // it doesn't exist\n```\n\nFeel free to contribute more!\n\n## FAQ\n\n<details>\n\n<summary>Which get method should I use?</summary>\n\nBased on [the Guiding Principles](#guiding-principles), your test should\nresemble how your code (component, page, etc.) as much as possible. With this\nin mind, we recommend this order of priority:\n\n1.  `getByLabelText`: Only really good for form fields, but this is the number 1\n    method a user finds those elements, so it should be your top preference.\n2.  `getByPlaceholderText`: [A placeholder is not a substitute for a label](https://www.nngroup.com/articles/form-design-placeholders/).\n    But if that's all you have, then it's better than alternatives.\n3.  `getByText`: Not useful for forms, but this is the number 1 method a user\n    finds other elements (like buttons to click), so it should be your top\n    preference for non-form elements.\n4.  `getByAltText`: If your element is one which supports `alt` text\n    (`img`, `area`, and `input`), then you can use this to find that element.\n5.  `getByTestId`: The user cannot see (or hear) these, so this is only\n    recommended for cases where you can't match by text or it doesn't make sense\n    (the text is dynamic).\n\nOther than that, you can also use the `container` to query the rendered\ncomponent as well (using the regular\n[`querySelector` API](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)).\n\n</details>\n\n<details>\n\n<summary>Can I write unit tests with this library?</summary>\n\nDefinitely yes! You can write unit and integration tests with this library.\nSee below for more on how to mock dependencies (because this library\nintentionally does NOT support shallow rendering) if you want to unit test a\nhigh level component. The tests in this project show several examples of\nunit testing with this library.\n\nAs you write your tests, keep in mind:\n\n> The more your tests resemble the way your software is used, the more confidence they can give you. - [17 Feb 2018][guiding-principle]\n\n</details>\n\n<details>\n\n<summary>What if my app is localized and I don't have access to the text in test?</summary>\n\nThis is fairly common. Our first bit of advice is to try to get the default\ntext used in your tests. That will make everything much easier (more than just\nusing this utility). If that's not possible, then you're probably best\nto just stick with `data-testid`s (which is not bad anyway).\n\n</details>\n\n<details>\n\n<summary>What if I want to verify that an element does NOT exist?</summary>\n\nYou typically will get access to rendered elements using the `getByTestId` utility. However, that function will throw an error if the element isn't found. If you want to specifically test for the absence of an element, then you should use the `queryByTestId` utility which will return the element if found or `null` if not.\n\n```javascript\nexpect(queryByTestId('thing-that-does-not-exist')).toBeNull()\n```\n\n</details>\n\n<details>\n\n<summary>I really don't like data-testids, but none of the other queries make sense. Do I have to use a data-testid?</summary>\n\nDefinitely not. That said, a common reason people don't like the `data-testid`\nattribute is they're concerned about shipping that to production. I'd suggest\nthat you probably want some simple E2E tests that run in production on occasion\nto make certain that things are working smoothly. In that case the `data-testid`\nattributes will be very useful. Even if you don't run these in production, you\nmay want to run some E2E tests that run on the same code you're about to ship to\nproduction. In that case, the `data-testid` attributes will be valuable there as\nwell.\n\nAll that said, if you really don't want to ship `data-testid` attributes, then you\ncan use\n[this simple babel plugin](https://www.npmjs.com/package/babel-plugin-react-remove-properties)\nto remove them.\n\nIf you don't want to use them at all, then you can simply use regular DOM\nmethods and properties to query elements off your container.\n\n```javascript\nconst firstLiInDiv = container.querySelector('div li')\nconst allLisInDiv = container.querySelectorAll('div li')\nconst rootElement = container.firstChild\n```\n\n</details>\n\n<details>\n\n<summary>What if I’m iterating over a list of items that I want to put the data-testid=\"item\" attribute on. How do I distinguish them from each other?</summary>\n\nYou can make your selector just choose the one you want by including :nth-child in the selector.\n\n```javascript\nconst thirdLiInUl = container.querySelector('ul > li:nth-child(3)')\n```\n\nOr you could include the index or an ID in your attribute:\n\n```javascript\n<li data-testid={`item-${item.id}`}>{item.text}</li>\n```\n\nAnd then you could use the `getByTestId` utility:\n\n```javascript\nconst items = [\n  /* your items */\n]\nconst {getByTestId} = render(/* your component with the items */)\nconst thirdItem = getByTestId(`item-${items[2].id}`)\n```\n\n</details>\n\n<details>\n\n<summary>What about enzyme is \"bloated with complexity and features\" and \"encourage\npoor testing practices\"?</summary>\n\nMost of the damaging features have to do with encouraging testing implementation\ndetails. Primarily, these are\n[shallow rendering](http://airbnb.io/enzyme/docs/api/shallow.html), APIs which\nallow selecting rendered elements by component constructors, and APIs which\nallow you to get and interact with component instances (and their\nstate/properties) (most of enzyme's wrapper APIs allow this).\n\nThe guiding principle for this library is:\n\n> The more your tests resemble the way your software is used, the more confidence they can give you. - [17 Feb 2018][guiding-principle]\n\nBecause users can't directly interact with your app's component instances,\nassert on their internal state or what components they render, or call their\ninternal methods, doing those things in your tests reduce the confidence they're\nable to give you.\n\nThat's not to say that there's never a use case for doing those things, so they\nshould be possible to accomplish, just not the default and natural way to test\nPreact components.\n\n</details>\n\n## Guiding Principles\n\n> [The more your tests resemble the way your software is used, the more confidence they can give you.][guiding-principle]\n\nWe try to only expose methods and utilities that encourage you to write tests\nthat closely resemble how your Preact components are used.\n\nUtilities are included in this project based on the following guiding\nprinciples:\n\n1.  If it relates to rendering components, it deals with DOM nodes rather than\n    component instances, nor should it encourage dealing with component\n    instances.\n2.  It should be generally useful for testing individual Preact components or\n    full Preact applications. While this library is focused on the actual dom,\n    utilities could be included even if they don't directly relate to the actual dom.\n3.  Utility implementations and APIs should be simple and flexible.\n\nAt the end of the day, what we want is for this library to be pretty\nlight-weight, simple, and understandable.\n","readmeFilename":"README.md"}