{"id":13727161,"url":"https://github.com/Xiphe/test-real-styles","last_synced_at":"2025-05-07T22:30:51.135Z","repository":{"id":37102286,"uuid":"242762607","full_name":"Xiphe/test-real-styles","owner":"Xiphe","description":"(test-)framework agnostic utilities to test real styling of (virtual) dom elements","archived":false,"fork":false,"pushed_at":"2024-05-01T22:22:09.000Z","size":1094,"stargazers_count":38,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T09:51:19.155Z","etag":null,"topics":["browser-automation","component-testing","css","css-modules","dom-elements","jest","jsdom","playwright","testing-library","testing-tools","ui-testing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xiphe.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["Xiphe"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-02-24T14:50:08.000Z","updated_at":"2024-05-02T11:58:41.000Z","dependencies_parsed_at":"2024-01-06T07:55:43.658Z","dependency_job_id":"ff56723e-8a36-4191-812d-a972beb5553f","html_url":"https://github.com/Xiphe/test-real-styles","commit_stats":{"total_commits":73,"total_committers":2,"mean_commits":36.5,"dds":"0.34246575342465757","last_synced_commit":"c8694b8c00885f4f35cc6efcda0d1965de0cc3f6"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xiphe%2Ftest-real-styles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xiphe%2Ftest-real-styles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xiphe%2Ftest-real-styles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xiphe%2Ftest-real-styles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xiphe","download_url":"https://codeload.github.com/Xiphe/test-real-styles/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252452409,"owners_count":21750100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser-automation","component-testing","css","css-modules","dom-elements","jest","jsdom","playwright","testing-library","testing-tools","ui-testing"],"created_at":"2024-08-03T01:03:42.240Z","updated_at":"2025-05-07T22:30:50.203Z","avatar_url":"https://github.com/Xiphe.png","language":"TypeScript","readme":"# test-real-styles\n\n[![test \u0026 release](https://github.com/Xiphe/test-real-styles/actions/workflows/release.yml/badge.svg)](https://github.com/Xiphe/test-real-styles/actions/workflows/release.yml)\n[![codecov](https://codecov.io/gh/Xiphe/test-real-styles/branch/main/graph/badge.svg?token=LNLZ1IZK6W)](https://codecov.io/gh/Xiphe/test-real-styles)\n[![npm](https://img.shields.io/npm/v/test-real-styles)](https://www.npmjs.com/package/test-real-styles)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Love and Peace](http://love-and-peace.github.io/love-and-peace/badges/base/v1.0-small.svg)](https://github.com/love-and-peace/love-and-peace/blob/master/versions/base/v1.0/en.md)\n\n(test-)framework agnostic utilities to test real styling of (virtual) dom elements\n\n## Motivation\n\nI created this with [jest](https://jestjs.io/) and [testing-library](https://testing-library.com/)\nin mind to [programmatically test appearance effects of component APIs](https://xiphe.net/blog/testing/component-design-testing.html?rel=test-real-styles)\nin [real browsers](https://github.com/microsoft/playwright/).\n\nWhile [`@testing-library/jest-dom` has a `toHaveStyle` assertion](https://github.com/testing-library/jest-dom#tohavestyle) and there are [ways to test css-in-js](https://github.com/styled-components/jest-styled-components) all solutions I've tried ignore the [css cascade](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance)\nor use a [buggy/incomplete simulation of it](https://github.com/jsdom/jsdom/labels/css).\n\nBut real-world components do use the cascade. This library aims to give\nyou confidence that a style is actually active on an element.\n\n## Installation\n\n```bash\nnpm install test-real-styles\n```\n\n## Usage\n\nAssuming a [NodeJS](https://nodejs.org/en/) test environment with [jsdom](https://github.com/jsdom/jsdom) like [jest](https://jestjs.io/).\n\n```ts\nimport { getRealStyles, launch, toCss, LaunchedPage } from '../index';\n\nconst MY_CSS = `\n  button { background-color: fuchsia; }\n  button::after {\n    border: 2px solid olive;\n  }\n  button:hover { color: #123456; }\n  button:focus { color: rgba(255, 0, 123, 0.5); }\n`;\n\ndescribe(`button`, () =\u003e {\n  it('is pink', async () =\u003e {\n    /**\n     * This will\n     * - launch a headless chromium\n     * - insert the css\n     * - update the page with `doc`\n     * - return getComputedStyle(doc)['backgroundColor']\n     */\n    const styles = await getRealStyles({\n      css: MY_CSS,\n      doc: document.createElement('button'),\n      getStyles: ['backgroundColor'],\n    });\n\n    expect(styles).toEqual({ backgroundColor: 'fuchsia' });\n  });\n\n  describe('launch API', () =\u003e {\n    /* In case you want to re-use the browser, interact with the page or do stuff\n       before styles are returned */\n\n    let launchedPage: LaunchedPage | null = null;\n    beforeAll(() =\u003e {\n      launchedPage = launch('webkit', MY_CSS);\n    });\n\n    it('gets hover and focus styles', async () =\u003e {\n      const { updatePage, hover, focus, getStyles } = launchedPage!;\n      const button = document.createElement('button');\n      await updatePage(button);\n\n      await hover(button);\n      const hoverStyles = await getStyles(button, ['color', 'backgroundColor']);\n      await focus(button);\n      const focusStyles = await getStyles(button, ['color']);\n\n      expect(toCss(hoverStyles)).toMatchInlineSnapshot(`\n        \"color: #123456;\n        background-color: fuchsia;\"\n      `);\n      expect(focusStyles.color).toBe('rgba(255, 0, 123, 0.5)');\n    });\n\n    it('gets pseudo elements', async () =\u003e {\n      const { updatePage, getStyles } = launchedPage!;\n      const button = document.createElement('button');\n      await updatePage(button);\n\n      expect(\n        await getStyles(button, ['border'], { pseudoElt: '::after' }),\n      ).toEqual({ border: '2px solid olive' });\n    });\n  });\n});\n```\n\n## Examples\n\n- [Using Sass or other pre-processors](https://github.com/Xiphe/test-real-styles/blob/main/src/__tests__/sass.spec.tsx)\n- [Using CSS-Modules, React \u0026 TestingLibrary](https://github.com/Xiphe/test-real-styles/blob/main/src/__tests__/testingLibraryReact.spec.tsx)\n- [Using StyledComponents](https://github.com/Xiphe/test-real-styles/blob/main/src/__tests__/styledComponents.spec.tsx)\n- [Run test in multiple browsers parallel](https://github.com/Xiphe/test-real-styles/blob/main/src/__tests__/parallel.spec.tsx)\n\n## License\n\n\u003e The MIT License\n\u003e\n\u003e Copyright (C) 2022 Hannes Diercks\n\u003e\n\u003e Permission is hereby granted, free of charge, to any person obtaining a copy of\n\u003e this software and associated documentation files (the \"Software\"), to deal in\n\u003e the Software without restriction, including without limitation the rights to\n\u003e use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n\u003e of the Software, and to permit persons to whom the Software is furnished to do\n\u003e so, subject to the following conditions:\n\u003e\n\u003e The above copyright notice and this permission notice shall be included in all\n\u003e copies or substantial portions of the Software.\n\u003e\n\u003e THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\u003e IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n\u003e FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n\u003e COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n\u003e IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n\u003e CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","funding_links":["https://github.com/sponsors/Xiphe"],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FXiphe%2Ftest-real-styles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FXiphe%2Ftest-real-styles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FXiphe%2Ftest-real-styles/lists"}