{"id":34637784,"url":"https://github.com/lumapps/metrx","last_synced_at":"2025-12-24T17:11:49.687Z","repository":{"id":84169559,"uuid":"130175058","full_name":"lumapps/metrx","owner":"lumapps","description":"Measure web page performance metrics with ease.","archived":false,"fork":false,"pushed_at":"2018-11-02T03:04:24.000Z","size":1277,"stargazers_count":11,"open_issues_count":1,"forks_count":4,"subscribers_count":40,"default_branch":"master","last_synced_at":"2024-05-05T11:20:24.899Z","etag":null,"topics":["cli","performance","performance-analysis","puppeteer"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/lumapps.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}},"created_at":"2018-04-19T07:22:33.000Z","updated_at":"2023-09-13T07:29:31.000Z","dependencies_parsed_at":"2023-10-20T21:22:25.021Z","dependency_job_id":null,"html_url":"https://github.com/lumapps/metrx","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/lumapps/metrx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumapps%2Fmetrx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumapps%2Fmetrx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumapps%2Fmetrx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumapps%2Fmetrx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lumapps","download_url":"https://codeload.github.com/lumapps/metrx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lumapps%2Fmetrx/sbom","scorecard":{"id":605060,"data":{"date":"2025-08-11","repo":{"name":"github.com/lumapps/metrx","commit":"10b006c190c9235999f11ce0baa171d5f43e4b5d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":1,"reason":"Found 2/14 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":1,"reason":"9 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-pc5p-h8pf-mvwp","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-c2gp-86p4-5935","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T01:23:28.930Z","repository_id":84169559,"created_at":"2025-08-21T01:23:28.935Z","updated_at":"2025-08-21T01:23:28.935Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28005410,"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","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"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":["cli","performance","performance-analysis","puppeteer"],"created_at":"2025-12-24T17:08:14.323Z","updated_at":"2025-12-24T17:11:49.681Z","avatar_url":"https://github.com/lumapps.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# metrx\n\nThis tool measures any web application performances. This project uses [Puppeteer](https://github.com/GoogleChrome/puppeteer) to make painless automation.\n\nYou can read this [great article](https://michaljanaszek.com/blog/test-website-performance-with-puppeteer) written by `Michał Janaszek` for further information.\n\n\u003cp align=\"center\"\u003e\n    \u003cbr\u003e\n        \u003cimg width=480 src=\"https://github.com/lumapps/metrx/blob/master/metrx-example.gif?raw=true\" alt=\"metrx example\" /\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\n## Installation\n\nTo install metrx :\n\n```bash\nnpm install -g metrx\n```\n\n## Usage\n\nTo run the application, just use :\n\n```bash\nmetrx \u003curl\u003e\n```\n\nSeveral options are available to enhance metrics easily. Use `-h (--help)` to display them.\n\n```console\n➜ metrx -h\n\n  Usage: metrx [options] \u003curl ...\u003e\n\n  Measures web application loading metrics\n\n  Options:\n\n    -r, --repeat [n]                     The number of times the page metrics are measured (default: 5)\n    -w, --width [width]                  The viewport's width to set (default: 1920)\n    -H, --height [height]                The viewport's height to set (default: 1080)\n    -c, --custom-path [custom-path]      Path to custom path configuration file\n    -o, --output-format [output-format]  The desired output format (default: table)\n    --output-file [output-file]          Whether we want to export data in a file, and the desired path to the file\n    --wait-until [wait-until]            The waitUntil value of the Page.reload options accepted by puppeteer\n    --no-headless                        Defines if we dont want to use puppeteer headless mode\n    --no-sandbox                         Disable chrome sandbox mode, mandatory in some systems\n    -h, --help                           Output usage information\n```\n\n### Custom user path\n\nA custom file path can be set in the cli options. That way, you can tell puppeteer what it should do before measuring any kind of metric.\n\nThis option can be useful if you need to be logged in before being able to access your application.\n\nTo include your file into the process, just use `-c \u003crelative path to your file\u003e` option.\n\n```bash\nmetrx localhost:8000 -c '../../custom-path.js'\n```\n\nThe `custom-path.js` file shoud contain an exported ES module.\n\n```javascript\n// index.js: The custom path function is called like so :\nif (customPath) {\n    const customPathFunction = require(customPath);\n    await customPathFunction(page, logInfo);\n}\n\n// custom-path.js: example of login process\nconst LOGIN_INPUT = 'input[type=\"login\"]';\nconst PASSWORD_INPUT = 'input[type=\"password\"]';\n\nmodule.exports = async (page, logInfo) =\u003e {\n    const login = 'my-secret-login';\n    const password = 'my-really-secret-password';\n    const loginUrl = 'http://localhost:8080/login';\n\n    logInfo(`Loading ${loginUrl}`);\n\n    // Go to the login page url, and wait for the selector to be ready.\n    await page.goto(loginUrl);\n    await page.waitForSelector(LOGIN_INPUT);\n\n    logInfo('Logging in...');\n\n    // Type creditentials.\n    await page.type(LOGIN_INPUT, login);\n    await page.type(PASSWORD_INPUT, password);\n\n    logInfo('Redirecting');\n\n    // The process will continue once the redirect is resolved.\n    return page.waitForNavigation();\n};\n```\n\nThose functions have access to two arguments :\n\n-   `page` (The `Page` puppeteer object to be able to access the full [puppeteer page instance API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page))\n-   `logInfo` (To log custom informations)\n\n### Export data to a file\n\nYou can choose to export to multiple formats and export formated data to a file. For now, only `table`, `raw`, `json` and `csv` are available.\n`table` and `raw` data will be exported to a `txt` file. To use it, just type :\n\n```bash\nmetrx localhost:8000 --output-format json --output-file ~/results.json\n```\n\nIf you don't provide any filename, a file will automatically be created in your current directory.\n\n### \"Wait until\" option\n\nTo make a page reload, `metrx` does a `Page.reload()` from puppeteer's `Page` object. This object accepts a `waitUntil` parameter, which defines when the page navigation has succeeded, and when the application should collect the metrics and reload the page. You can find more information about `Page.reload()` [right here](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagereloadoptions).\n\nTo use, just add the `--wait-until` flag and the desired options. Since `Page.reload` accepts either a `String` or an `Array` of `Strings`, if you want to add multiple values, just split them with a `,`\n\nFor example:\n\n```bash\nmetrx localhost:8000 --wait-until networkidle0,load\n```\n\n## Development\n\nTo contribute, just run the following commands :\n\n```shell\ngit clone https://github.com/lumapps/metrx.git\n\ncd metrx\n\nnpm install\n```\n\nThen, to use `metrx` just run it via `cli.js`, for example :\n\n```shell\n./cli.js http://localhost:8000\n```\n\n## Useful Resources\n\n-   [Commander documentation](https://github.com/tj/commander.js)\n-   [Puppeteer API](https://pptr.dev/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flumapps%2Fmetrx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flumapps%2Fmetrx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flumapps%2Fmetrx/lists"}