{"id":32397909,"url":"https://github.com/cyrilschumacher/flexpect","last_synced_at":"2026-06-22T10:32:21.087Z","repository":{"id":309092713,"uuid":"1034977845","full_name":"cyrilschumacher/flexpect","owner":"cyrilschumacher","description":"Automated layout validation tool using Playwright. Ensures responsive design accuracy across multiple viewports by inspecting element positions and visual alignment.","archived":false,"fork":false,"pushed_at":"2026-05-09T01:35:13.000Z","size":1607,"stargazers_count":1,"open_issues_count":11,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T07:38:04.344Z","etag":null,"topics":["automation","front-end-testing","playwright","responsive-design","testing","ui-testing","visual-regression"],"latest_commit_sha":null,"homepage":"https://cyrilschumacher.github.io/flexpect/","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/cyrilschumacher.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-09T11:48:09.000Z","updated_at":"2026-03-28T13:57:00.000Z","dependencies_parsed_at":"2025-08-09T20:36:28.806Z","dependency_job_id":"1a36a546-415d-4c37-8306-9362c2cbad7d","html_url":"https://github.com/cyrilschumacher/flexpect","commit_stats":null,"previous_names":["cyrilschumacher/flexpect"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/cyrilschumacher/flexpect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilschumacher%2Fflexpect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilschumacher%2Fflexpect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilschumacher%2Fflexpect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilschumacher%2Fflexpect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cyrilschumacher","download_url":"https://codeload.github.com/cyrilschumacher/flexpect/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilschumacher%2Fflexpect/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34645681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-22T02:00:06.391Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["automation","front-end-testing","playwright","responsive-design","testing","ui-testing","visual-regression"],"created_at":"2025-10-25T07:56:41.416Z","updated_at":"2026-06-22T10:32:21.082Z","avatar_url":"https://github.com/cyrilschumacher.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg alt=\"Flexpect logo\" src=\"logo.png\" /\u003e\n\n[![NPM Package][npm-package-image]][npm-package-url]\n[![MIT License][license-image]][license-url]\n[![CI][ci-image]][ci-url]\n[![Codacy][codacy-image]][codacy-url]\n[![codecov][codecov-image]][codecov-url]\n\n\u003e Automated layout validation tool using Playwright. Ensures responsive design accuracy across multiple viewports by inspecting element positions and visual alignment.\n\nEnsuring consistent visual alignment across responsive layouts is a recurring challenge in front-end development. Small CSS changes or unintended layout shifts can break the alignment between related elements (for example, labels and inputs, icons and text blocks, or mirrored components across mobile and desktop pages), and these regressions are often hard to catch with functional tests alone. Visual test snapshots help, but they can be noisy and brittle for layout-specific assertions.\n\nThis library provides Playwright matchers focused specifically on geometric relationships between elements: **horizontal and vertical alignment, equal widths or heights, centered positioning, and other spatial checks**. By expressing layout expectations as deterministic assertions, teams can:\n\n- Detect regressions in alignment early\n- Prevent cascading visual bugs\n- Keep responsive pages consistent between mobile and desktop variants\n\nThe matchers integrate naturally with Playwright tests and return clear diagnostics (positions and sizes) to make failures actionable and reduce the feedback loop for front-end fixes.\n\n## Installation\n\n```bash\nnpm install --save-dev flexpect\n```\n\nTo register all matchers automatically, you can still use:\n\n```typescript\n// playwright.config.ts or global-setup file\nimport 'flexpect/register'; // registers custom expect matchers\n```\n\nIf you prefer not to register all matchers provided by flexpect, you can import and register only the ones you need manually in your Playwright setup (or any other test runner like Jest or Vitest):\n\n```typescript\nimport { expect } from '@playwright/test';\nimport { toBeAlignedWith, toHaveAspectRatio } from 'flexpect';\n\n// Register only the matchers you need\nexpect.extend({ toBeAlignedWith, toHaveAspectRatio });\n```\n\nThis approach allows you to:\n\n- load only the matchers you actually use,\n- keep full control over which matchers are registered in your test environment.\n\n## Quick start\n\nExample: assert two elements are horizontally aligned within a 2px tolerance.\n\n```typescript\n// test.spec.ts\ntest('labels align with inputs', async ({ page }) =\u003e {\n  const label = await page.locator('label[for=\"email\"]');\n  const input = await page.locator('#email');\n  await expect(label).toBeAlignedWith(input, Axis.Horizontal, Alignment.Start, {\n    tolerance: 2,\n    toleranceUnit: ToleranceUnit.Pixel,\n  });\n});\n```\n\nExample: assert same width\n\n```typescript\nawait expect(cardA).toHaveSameWidthAs(cardB, { tolerance: 17, toleranceUnit: ToleranceUnit.Percent });\n```\n\n## Examples\n\n- Cross-breakpoint consistency: run the same assertions on a mobile and desktop viewport to ensure responsive parity.\n- Form layout invariants: label baseline alignment, icon alignment inside buttons.\n- Component contract tests: enforce that mirrored components keep the same width/height across variants.\n\nSee the `test` folder for full test files and fixtures.\n\nFor detailed documentation on all available matchers and their usage, please visit the [documentation](https://cyrilschumacher.github.io/flexpect/).\n\n## Contributing\n\nContributions welcome. Workflow:\n\n- Fork the repository.\n- Create a feature branch: git checkout -b feat/my-feature\n- Commit changes and push.\n- Open a pull request describing the change and rationale; include tests where possible.\n\nPlease follow the existing code style and include unit and integration tests for new matchers.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n[npm-package-image]: https://img.shields.io/npm/v/flexpect\n[npm-package-url]: https://www.npmjs.com/package/flexpect\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: LICENSE\n[ci-image]: https://github.com/cyrilschumacher/flexpect/actions/workflows/ci.yml/badge.svg?branch=main\n[ci-url]: https://github.com/cyrilschumacher/flexpect/actions/workflows/ci.yml\n[codecov-image]: https://codecov.io/gh/cyrilschumacher/flexpect/graph/badge.svg?token=RTYOKUQF7Z\n[codecov-url]: https://codecov.io/gh/cyrilschumacher/flexpect\n[codacy-image]: https://app.codacy.com/project/badge/Grade/a908d94ab6ef47bc90ff07512a5519bb\n[codacy-url]: https://app.codacy.com/gh/cyrilschumacher/flexpect/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyrilschumacher%2Fflexpect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcyrilschumacher%2Fflexpect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyrilschumacher%2Fflexpect/lists"}