{"id":13802339,"url":"https://github.com/jimthedev/timecafe","last_synced_at":"2025-10-29T12:30:33.253Z","repository":{"id":57377169,"uuid":"88287513","full_name":"jimthedev/timecafe","owner":"jimthedev","description":"Timing / performance information for your TestCafe test tasks.","archived":false,"fork":false,"pushed_at":"2017-04-14T19:41:25.000Z","size":20,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-05-14T03:45:38.740Z","etag":null,"topics":["browser-testing","nodejs","performance","performance-testing","test","testcafe","testing","tests"],"latest_commit_sha":null,"homepage":"https://npm.im/timecafe","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jimthedev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-14T17:15:28.000Z","updated_at":"2020-05-25T13:21:53.000Z","dependencies_parsed_at":"2022-09-06T01:22:24.791Z","dependency_job_id":null,"html_url":"https://github.com/jimthedev/timecafe","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimthedev%2Ftimecafe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimthedev%2Ftimecafe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimthedev%2Ftimecafe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimthedev%2Ftimecafe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jimthedev","download_url":"https://codeload.github.com/jimthedev/timecafe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219857782,"owners_count":16556055,"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-testing","nodejs","performance","performance-testing","test","testcafe","testing","tests"],"created_at":"2024-08-04T00:01:42.331Z","updated_at":"2025-10-29T12:30:27.964Z","avatar_url":"https://github.com/jimthedev.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TimeCafe\n\n\u003e Timing / performance information for your [TestCafe](https://github.com/DevExpress/testcafe) test tasks.\n\nTestCafe does a great job but it unfortunately only gives you timing for the entire run and not per task.  Task timing is especially important when looking for performance regressions.\n\nIt might seem if this was as simple as adding a beforeEach and afterEach with a timer but unfortunately in TestCafe the afterEach fires very late and does not give you an accurate view of timing.  TimeCafe allows you to use beforeEach while allowing you to manually stop the timers at the end of your tests.  This method provides more accurate results.\n\nOther gotchas are that sometimes we want to perform reset operations between tests. For example, you might want to go back to the login screen between tests. With that said, we don't want to test this part of the operation, only the part that happens on once the actual test begins. For this reason we provide a few helpers so that you can provide your own reset function without it counting against your performance metrics.  Essentially a reset function gets a free pass from a performance standpoint since it really isn't part of the feature under test.\n\n## Prerequisites\n\n- Install testcafe locally in your project.\n- Install timecafe `yarn add timecafe --dev  # or: npm install --save-dev timecafe`\n\n## Usage\n\nYou must do three to use TimeCafe:\n\n- Provide a reset function (to be run untimed between timed tests)\n- Add some code tests that you want timed\n- Run the test command!\n\n### The reset function\n\nThe reset function is probably the hardest part of setting up TimeCafe but once it is done, you'll use it in all your tests.\n\nCreate a file to hold your reset functionality. Remember that this is the untimed functionality that will run between timed tests. It can still have assertions in it of course.  Let's call this `login.js` (note that we don't include .test.js as the extension since it will be imported into our tests). All our reset function is doing is saying that between tests we want the browser to go back to the login page.\n\n```javascript\nimport { Selector } from 'testcafe';\nimport timecafe from 'timecafe';\n\nconst login = async t =\u003e {\n  await t.navigateTo('http://localhost:9000/login');\n  const contentArea = await Selector('.content-area').find('h1');\n\n  await t\n    .expect(contentArea.innerText)\n    .contains('Login:', 'The login header is shown');\n};\n\nexport default login;\nexport const time = timecafe(login);\n```\n\nNotice that there are two exports, one is the original login function. The second is variable called `time`. By wrapping your reset function in timecafe() you're making sure that any tests you'd like to time will be able to do so. We're almost done but there is one important part left. Let's look at how you would actually time a test using the reset function that we previously defined in `login.js`.\n\n### Your tests that you want timed\n\nOk, we've got `login.js` done so now we just need to use it in our tests.\n\nFirst, if you don't already have a file to put your tests in, let's do so now. Create `index.test.js` and add something resembling the following. Note the selectors being used are based on an Angular 1 app so you should swap them out with your own:\n\n```javascript\nimport { Selector } from \"testcafe\";\nimport {time} from './login';\n\n// NOTE IMPORTANT MAKE SURE THAT YOU PUT IN AN EXACT URL AND NOT ONE THAT WILL REDIRECT\n// OTHERWISE THE PAGE WILL REDIRECT AND BE BLOWN AWAY\nfixture `Admin Testing`\n  .page `http://localhost:9000/login`\n  .beforeEach(time.start());\n\ntest(\"App builder\", async t =\u003e {\n  // Action\n  await t.click('a[ui-sref=\"admin\"]').click('a[ui-sref=\"admin.builder\"]');\n\n  // Query\n  const subHeader = await Selector(\".content-area\").find(\"ui-view\").find(\"h5\");\n\n  // Test\n  await t\n    .expect(subHeader.innerText)\n    .contains(\"app builder\", \"The app builder header is displayed\");\n\n  // Always return to the login screen (manually this time) when done to stop the counter\n  await time.finish(t);\n});\n\n```\n\nPlease note that time.start() does not require you to pass in a test explicitly, however time.finish(t) does require it because it needs to know which test to actually register as finished.\n\n### Run the tests\n\nYou can execute your tests with `$(npm bin)/testcafe chrome ./index.test.js -e`\n\nAnd you should expect output that looks like this:\n\n```bash\nRunning tests in:\n- Chrome 57.0.2987 / Mac OS X 10.12.4\n\nAdmin Testing\n\n  Done in 0.422129062s.\n✓ App builder\n\n\n1 passed (2s)\n```\n\nNote that due to current limitations the time actually is recorded directly before the test name.\n\n## Additional notes\n\nInternally we use node's high resolution timing function `process.hrtime()`.\n\nIronically tests don't exist.\n\n## Author\n\nJim Cummins ([@jimthedev](https://twitter.com/jimthedev))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimthedev%2Ftimecafe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjimthedev%2Ftimecafe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimthedev%2Ftimecafe/lists"}