{"id":17488485,"url":"https://github.com/smastrom/cypress-wait-frames","last_synced_at":"2025-03-28T15:42:12.272Z","repository":{"id":65404773,"uuid":"591439122","full_name":"smastrom/cypress-wait-frames","owner":"smastrom","description":"🪂 Cypress command to wait for any CSS/DOM property to be idle after n frames.","archived":false,"fork":false,"pushed_at":"2023-12-09T20:36:50.000Z","size":1075,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T01:51:39.519Z","etag":null,"topics":["cypress","cypress-command","cypress-css","cypress-frames","cypress-promise","cypress-raf","cypress-scroll","cypress-wait"],"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/smastrom.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2023-01-20T19:02:33.000Z","updated_at":"2024-06-18T23:16:06.000Z","dependencies_parsed_at":"2024-12-08T05:00:19.647Z","dependency_job_id":null,"html_url":"https://github.com/smastrom/cypress-wait-frames","commit_stats":{"total_commits":34,"total_committers":2,"mean_commits":17.0,"dds":"0.17647058823529416","last_synced_commit":"c232e48f47195d7dd8d86f20900268000653866e"},"previous_names":["smastrom/cypress-wait-frames"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smastrom%2Fcypress-wait-frames","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smastrom%2Fcypress-wait-frames/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smastrom%2Fcypress-wait-frames/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smastrom%2Fcypress-wait-frames/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smastrom","download_url":"https://codeload.github.com/smastrom/cypress-wait-frames/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246056662,"owners_count":20716782,"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":["cypress","cypress-command","cypress-css","cypress-frames","cypress-promise","cypress-raf","cypress-scroll","cypress-wait"],"created_at":"2024-10-19T04:08:01.405Z","updated_at":"2025-03-28T15:42:12.255Z","avatar_url":"https://github.com/smastrom.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![npm](https://img.shields.io/npm/v/cypress-wait-frames?color=46c119) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/smastrom/cypress-wait-frames/tests.yml?branch=main\u0026label=tests) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/cypress-wait-frames?color=success)\n![dependency-count](https://img.shields.io/badge/dependency%20count-0-success)\n\n# Cypress Wait Frames\n\nCypress command to wait for any CSS/DOM property to be idle after a specified number of frames.\n\n\u003cbr /\u003e\n\n## Installation\n\n```bash\npnpm add cypress-wait-frames\n```\n\nImport the package in your **commands.js**:\n\n```js\nimport 'cypress-wait-frames'\n```\n\n\u003cbr /\u003e\n\nIf using TypeScript, optionally install the latest version of [csstype](https://www.npmjs.com/package/csstype) for CSS properties autocompletion:\n\n```bash\npnpm add -D csstype\n```\n\n\u003cbr /\u003e\n\n## Do I need this?\n\nCypress retry ability on [built-in assertions](https://docs.cypress.io/guides/core-concepts/retry-ability#Built-in-assertions) is very powerful and most likely you don't need this package or to use `cy.wait`. For example:\n\n```js\ncy.scrollTo(0, 1200)\n\n// No need for cy.wait(t) to make sure scroll is completed\n\ncy.window().eq('scrollY').should('be.approximately', 1200, 2) // Will retry until it passes\n```\n\nDocumentation on [retry-ability](https://docs.cypress.io/guides/core-concepts/retry-ability) is very detailed and it might already contain the answer you're looking for.\n\n\u003cbr /\u003e\n\n## When I find it useful\n\nThere are cases where it's very hard to retain retry-ability and you might find yourself guessing timings using `cy.wait` or increasing the retry-ability timeout.\n\nFor example when asserting properties not available within Cypress queries:\n\n```js\ncy.get('h1').eq(15).scrollIntoView()\n\n// Need to add cy.wait(t) to make sure scroll is completed\n\ncy.get('h1')\n  .eq(15)\n  .then((el) =\u003e {\n    cy.wrap(el[0].getBoundingClientRect().top).should('be.approximately', 0, 2)\n  })\n```\n\nBut scenarios can be disparate and more complex. Bottom line is that if you find yourself using `cy.wait()` as last resort to obtain values or to wait for DOM/CSS properties to be idle, this package might be useful.\n\n\u003cbr /\u003e\n\n## Usage\n\n### Window\n\n```js\ncy.waitFrames({\n  subject: cy.window,\n  property: 'outerWidth'\n})\n\ncy.log('Resized!') // Executed once 'outerWidth' isn't changed for 20 frames (default).\n```\n\n### DocumentElement\n\n```js\ncy.waitFrames({\n  subject: () =\u003e cy.get('html'),\n  property: 'clientWidth',\n  frames: 10\n})\n\ncy.log('Resized!') // Executed once 'clientWidth' isn't changed for 10 frames.\n```\n\n### HTMLElement / SVGElement\n\n```js\ncy.waitFrames({\n  subject: () =\u003e cy.get('a').eq(0),\n  property: 'getBoundingClientRect.top'\n}).then(([{ value }]) =\u003e {\n  cy.wrap(value).should('be.approximately', 0, 2) // Asserts that top is 0 after 20 frames (default).\n})\n```\n\n### Options\n\n| Property   | Default    | Type                                                                              | Description                                             | Required           |\n| ---------- | ---------- | --------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------ |\n| `subject`  | undefined  | `() =\u003e Cypress.Chainable\u003cCypress.AutWindow \\| JQuery\u003cHTMLElement \\| SVGElement\u003e\u003e` | Subject to watch.                                       | :white_check_mark: |\n| `property` | undefined  | `string \\| string[]`                                                              | One or more properties to watch.                        | :white_check_mark: |\n| `frames`   | 20         | `number`                                                                          | Number of frames to wait.                               | :x:                |\n| `timeout`  | 30 \\* 1000 | `number`                                                                          | Timeout in milliseconds before the command should fail. | :x:                |\n\n\u003cbr /\u003e\n\n## Yields\n\nA [Cypress Promise](https://docs.cypress.io/api/utilities/promise) which resolves to an array of objects (one for each property) or throws an error if `timeout` is reached:\n\n| Property   | Type                         | Description                                     |\n| ---------- | ---------------------------- | ----------------------------------------------- |\n| `subject`  | `AUTWindow` \\| `HTMLElement` | Subject yielded from `subject` option chainer.  |\n| `value`    | `Primitive`                  | Property value at which the function resolved.  |\n| `property` | `string`                     | Awaited property name.                          |\n| `time`     | `DOMHighResTimestamp`        | Time in ms that took to resolve since invoking. |\n\n\u003cbr /\u003e\n\n## Properties\n\n### DOM properties\n\n```js\ncy.waitFrames({\n  subject: () =\u003e cy.get('html'),\n  property: 'clientWidth'\n})\n```\n\n### CSS properties\n\n```js\ncy.waitFrames({\n  subject: () =\u003e cy.get('#my-element'),\n  property: 'background-color'\n})\n```\n\n:bulb: Use _kebab-case_ for CSS properties. [getComputedStyle](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle) is used internally to get the values.\n\n### Nested properties / methods\n\nYou can watch for methods or objects **maximum 1 nested property** which returns a primitive.\n\n```js\ncy.waitFrames({\n  subject: cy.window,\n  property: 'visualViewport.offsetTop'\n})\n```\n\n```js\ncy.waitFrames({\n  subject: () =\u003e cy.get('a').eq(0),\n  property: 'getBoundingClientRect.top'\n})\n```\n\n:warning: Methods with arity greater than 0 are not supported, (e.g. `getAttribute('href')`).\n\n### Mixed properties / methods\n\nYou can watch for multiple properties as well, `waitFrames` will resolve once all properties are idle:\n\n```js\ncy.waitFrames({\n  subject: () =\u003e cy.get('a').eq(0),\n  property: ['background-color', 'scrollTop', 'getBoundingClientRect.top']\n})\n```\n\n\u003cbr /\u003e\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmastrom%2Fcypress-wait-frames","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmastrom%2Fcypress-wait-frames","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmastrom%2Fcypress-wait-frames/lists"}