{"id":51140171,"url":"https://gitlab.com/gitlab-ci-utils/pagean","last_synced_at":"2026-06-25T22:00:43.394Z","repository":{"id":50270058,"uuid":"14485459","full_name":"gitlab-ci-utils/pagean","owner":"gitlab-ci-utils","description":"Pagean is a web page analysis tool designed to automate tests requiring web pages to be loaded in a browser window, e.g. checking for horizontal scrollbar, console errors, broken links.","archived":false,"fork":false,"pushed_at":null,"size":null,"stargazers_count":0,"open_issues_count":19,"forks_count":7,"subscribers_count":null,"default_branch":"main","last_synced_at":"2025-04-01T16:56:48.974Z","etag":null,"topics":["container","node.js","npm"],"latest_commit_sha":null,"homepage":null,"language":null,"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":null,"metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2019-09-25T03:48:23.678Z","updated_at":"2025-03-31T23:39:26.886Z","dependencies_parsed_at":"2022-08-20T08:10:15.915Z","dependency_job_id":null,"html_url":"https://gitlab.com/gitlab-ci-utils/pagean","commit_stats":null,"previous_names":["gitlab-ci-utils/page-load-tests"],"tags_count":33,"template":null,"template_full_name":null,"purl":"pkg:gitlab/gitlab-ci-utils/pagean","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/gitlab-ci-utils%2Fpagean","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/gitlab-ci-utils%2Fpagean/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/gitlab-ci-utils%2Fpagean/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/gitlab-ci-utils%2Fpagean/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/owners/gitlab-ci-utils","download_url":"https://gitlab.com/gitlab-ci-utils/pagean/-/archive/main/pagean-main.zip","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/gitlab-ci-utils%2Fpagean/sbom","scorecard":null,"host":{"name":"gitlab.com","url":"https://gitlab.com","kind":"gitlab","repositories_count":4521539,"owners_count":7348,"icon_url":"https://github.com/gitlab.png","version":null,"created_at":"2022-05-30T11:31:42.605Z","updated_at":"2026-06-04T14:33:06.434Z","status":"online","status_checked_at":"2026-06-25T02:00:05.761Z","response_time":228,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.382Z","robots_txt_url":"https://gitlab.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/owners"}},"keywords":["container","node.js","npm"],"created_at":"2026-06-25T22:00:37.450Z","updated_at":"2026-06-25T22:00:43.386Z","avatar_url":null,"language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pagean\n\nPagean is a web page analysis tool designed to automate tests requiring web\npages to be loaded in a browser window (for example 404 error loading an\nexternal resource, page renders with horizontal scrollbars). The specific tests\nare outlined below, but are all general tests that do not include any\npage-specific logic.\n\n## Installation\n\nInstall Pagean globally (as shown below), or locally, via\n[npm](https://www.npmjs.com/).\n\n```\nnpm install -g pagean\n```\n\nIf `puppeteer` issues are encountered during installation, see the\n[system requirements](https://github.com/puppeteer/puppeteer/blob/main/docs/guides/system-requirements.md)\nfor complete details. These should be standard for most installations.\n\n## Usage\n\nPagean runs as a command line tool and is executed as follows:\n\n```\nInstalled globally:\n\u003e pagean [options]\n\nInstalled locally:\n\u003e npx pagean [options]\n\nOptions:\n  -V, --version        output the version number\n  -c, --config \u003cfile\u003e  the path to the pagean configuration file (default: \"./.pageanrc.json\")\n  -h, --help           display help for command\n```\n\nPagean requires a configuration file named, which can be specified via the CLI\nas detailed previously, or use the default file `.pageanrc.json` in the project\nroot. This file provides the URLs to be tested and options to configure the\ntests and reports. Details on the available tests and the configuration file\nformat are provided below.\n\n## Test cases\n\nThe tests use [Puppeteer](https://github.com/GoogleChrome/puppeteer) to launch\na headless Chrome browser. The URLs defined in the configuration file are each\nloaded once, and after page load the applicable tests are executed. Test\nresults are `passed` or `failed`, but can be configured to report `warning`\ninstead of failure. Only a `failed` test causes the test process to fail and\nexit with an error code (a `warning` does not). If a page URL fails to load,\nit is retried up to two additional times and if unsuccessful the URL is\nlogged as a `page error` with the error message.\n\n### Broken link test\n\nThe broken link test checks for broken links on the page. It checks any `\u003ca\u003e`\ntag on the page with `href` pointing to another location on the current page or\nanother page (that is, only `http(s)` or `file` protocols).\n\n- For links within the page, this test checks for existence of the element on\n  the page, passing if the element exists and failing otherwise (and passing\n  for cases that are always valid, for example `#` or `#top` for the current\n  page). It doesn't check the visibility of the element. Failing tests return a\n  response of \"#element Not Found\" (where `#element` identifies the specific\n  element).\n- For links to other pages, the test tries to most efficiently confirm whether\n  the target link is valid. It first makes a `HEAD` request for that URL and\n  checks the response. If an erroneous response is returned (\u003e= 400 with no\n  execution error) and not code 429 (Too Many Requests), the request is retried\n  with a `GET` request. The test passes for HTTP responses \u003c 400 and fails\n  otherwise (if HTTP response is \u003e= 400 or another error occurs).\n  - This can result in false failure indications, specifically for `file:`\n    links (`404` or `ECONNREFUSED`) or where the browser passes a domain\n    identity with the request (page loads when tested, but `401` response for\n    links to that page). For these cases, or other false failures, the test\n    configuration allows a Boolean `checkWithBrowser` option that instead\n    checks links by loading the target in the browser (via `puppeteer`). Note\n    this can increase test execution time, in some cases substantially, due to\n    the time to open a new browser tab and plus load the page and all assets.\n  - Note that `file:` links can only be tested with the `checkWithBrowser`\n    option.\n  - If the link to another page includes a hash it's removed prior to checking.\n    The test in this case is confirming a valid link, not that the element\n    exists, which is only done for the current page.\n  - The test configuration allows an `ignoredLinks` array listing link URLs to\n    ignore for this test. Note this only applies to links to other pages, not\n    links within the page, which are always checked.\n- To optimize performance, link test results are cached and those links aren't\n  re-tested for the entire test run (across all tested URLs). The test\n  configuration allows a Boolean `ignoreDuplicates` option that can be set to\n  `false` to bypass this behavior and re-test all links. The results for any\n  failed links are included in the reports in any case.\n\nFor any failing test, the `data` array in the test report includes the original\nURL and the response code or error as shown below.\n\n```json\n[\n  {\n    \"href\": \"https://about.gitlab.com/not-found\",\n    \"status\": 404\n  },\n  {\n    \"href\": \"http://localhost:3000/brokenLinks.html#notlinked\",\n    \"status\": \"#notlinked Not Found\"\n  },\n  {\n    \"href\": \"https://this.url.does.not.exist/\",\n    \"status\": \"ENOTFOUND\"\n  }\n]\n```\n\nNote: this test checks all links on the page, and doesn't respect mechanisms\nintended to limit web crawlers such as `robots.txt` or `noindex` tags.\n\n### Console error test\n\nThe console error test fails if any error is written to the browser console,\nbut is otherwise simply a subset of the console output test. This separation\nallows for testing for console errors, but allowing any other console output.\n\n### Console output test\n\nThe console output test fails if any output is written to the browser console.\nAn array is included in the report with all entries, as shown below:\n\n```json\n[\n  {\n    \"type\": \"error\",\n    \"text\": \"Failed to load resource: net::ERR_NAME_NOT_RESOLVED\",\n    \"location\": {\n      \"url\": \"https://this.url.does.not.exist/file.js\"\n    }\n  }\n]\n```\n\n### External script test\n\nThe external script test is intended to identify any externally loaded\nJavaScript files (for example loaded from a CDN) and aggregate those files so\nthey can undergo further analysis (for example dependency vulnerability\nscanning). The test is included here since these tests load fully rendered\npages, therefore allowing the aggregation of this data for pages generated\nusing any language or framework. By default the test returns a warning if the\npage includes any JavaScript files loaded from a different domain than the page\n(although this could be overridden to fail instead via setting\n`failWarn: false`, see the Configuration section below). These files are then\ndownloaded and saved in the \"pagean-external-files\" directory in the project\nroot. Subdirectories are created for each domain, then following the URL path.\nFor example, the following script…\n\n```html\n\u003cscript src=\"https://bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js\"\u003e\u003c/script\u003e\n```\n\n…is saved as `./bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js`. The\n`data` array in the test report includes the original file URL and the local\nsaved filename or applicable error, as shown below.\n\n```json\n[\n  {\n    \"url\": \"https://code.jquery.com/jquery-3.4.1.slim.min.js\",\n    \"localFile\": \"pagean-external-scripts/code.jquery.com/jquery-3.4.1.slim.min.js\"\n  },\n  {\n    \"url\": \"http://bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js\",\n    \"error\": \"Request failed with status code 404\"\n  }\n]\n```\n\nEach external script is saved only once, but is reported on any page where it's\nreferenced.\n\n### Horizontal scrollbar test\n\nThe horizontal scrollbar test fails if the rendered page has a horizontal\nscrollbar. If a specific browser viewport size is desired for this test, that\ncan be configured in the `puppeteerLaunchOptions`.\n\n### Page load time test\n\nThe page load time test fails if the page load time (from start through the\n`load` event) exceeds the defined threshold in the configuration file (or the\ndefault of 2 seconds). The actual load time is included in the report. Tests\ntime out at twice the page load time threshold.\n\n### Rendered HTML test\n\nThe rendered HTML test is intended for cases where content is dynamically\ncreated prior to page load (that is, the `load` event firing). The rendered\nHTML is returned and checked with\n[HTML Hint](https://www.npmjs.com/package/htmlhint) and the test fails if any\nissues are found. An array is included in the report with all HTML Hint issues,\nas shown below:\n\n```json\n[\n  {\n    \"col\": 9,\n    \"evidence\": \"    \u003cdiv id=\\\"div1\\\"\u003e\u003c/div\u003e\",\n    \"line\": 6,\n    \"message\": \"The id value [ div1 ] must be unique.\",\n    \"raw\": \" id=\\\"div1\\\"\",\n    \"rule\": {\n      \"description\": \"The value of id attributes must be unique.\",\n      \"id\": \"id-unique\",\n      \"link\": \"https://github.com/thedaviddias/HTMLHint/wiki/id-unique\"\n    },\n    \"type\": \"error\"\n  }\n]\n```\n\nAn htmlhintrc file can be specified in the configuration file, otherwise the\ndefault \"./.htmlhintrc\" file is used (if it exists). See the Configuration\nsection below.\n\nNote: this test may not find some errors in the original HTML that are\nremoved/resolved as the page is parsed (for example closing tags with no\nopening tags).\n\n## Reports\n\nBased on the `reporters` configuration, Pagean results may be displayed in the\nconsole and saved in two reports in the project root directory (any or all of\nthe three):\n\n- A JSON report named\n  [`pagean-results.json`](https://gitlab-ci-utils.gitlab.io/pagean/pagean-results.json).\n- An HTML report named\n  [`pagean-results.html`](https://gitlab-ci-utils.gitlab.io/pagean/pagean-results.html).\n\nBoth reports contain:\n\n- The time of test execution.\n- A summary of the total tests and results (passed, warning, failed, and page\n  errors).\n- The detailed test results, including the URL tested, list of tests performed\n  on that URL with results, and, if applicable, any relevant data associated\n  with the test failure (for example the console errors if the console error\n  test fails).\n\nComplete reports for the example case in this project (the tests as specified\nin the project\n[`.pageanrc.json`](https://gitlab.com/gitlab-ci-utils/pagean/-/blob/master/.pageanrc.json)\nfile) can be found at the preceding links.\n\n## Configuration\n\nPagean looks for a configuration file as specified via the CLI, or defaults to\na file named `.pageanrc.json` in the project root. If the configuration file is\nnot found, is not valid JSON, or doesn't contain any URLs to check the job\nfails.\n\nBelow is an example `.pageanrc.json` file, which is broken into seven major\nproperties:\n\n- `htmlhintrc`: An optional path to an htmlhintrc file to be used in the\n  rendered HTML test.\n- `project`: An optional name of the project, which is included in HTML and\n  JSON reports.\n- `puppeteerLaunchOptions`: An optional set of options to pass to Puppeteer on\n  launch. The complete list of available options can be found at\n  https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions.\n- `reporters`: An optional array of reporters indicating the test reports that\n  should be provided. There are three possible options - `cli`, `html`, and\n  `json`. The `cli` option reports all test details to the console, but the\n  final results summary is always output (even with `cli` disabled). If\n  `reporters` is specified, at least one reporter must be included. The default\n  value, as specified below, is all three reporters enabled.\n- `settings`: These settings enable/disable or configure tests, and are applied\n  to all tests overriding the default values.\n  - The shorthand notation allows easy enabling/disabling of tests. In this\n    format the test name is given with a Boolean value to enable or disable the\n    test. In this case any other test-specific settings use the default values.\n  - The longhand version includes an object for each test. Every test includes\n    two possible properties (some tests include additional settings):\n    - `enabled`: A Boolean value to enable/disable the test, and some tests\n      include additional settings (default `true` for all tests).\n    - `failWarn`: A Boolean value causing a failed test to report a warning\n      instead of failure. A warning result doesn't cause the test process to\n      fail (exit with an error code). The default value for all tests is\n      `false` except the `externalScriptTest`, as shown below.\n\nThe shorthand:\n\n```json\n\"settings\": {\n    \"consoleErrorTest\": true\n}\n```\n\nis equivalent to the longhand:\n\n```json\n\"settings\": {\n    \"consoleErrorTest\": {\n        \"enabled\": true,\n        \"failWarn\": false\n    }\n}\n```\n\n- `sitemap`: Specify a sitemap with URLs to test. If a sitemap is specified,\n  the URLs from the sitemap are added to the `urls` array. If a URL is in the\n  `urls` array with `settings`, those settings are retained. Note that\n  `\u003csitemapindex\u003e` is currently not supported. The `sitemap` object can have\n  the following properties:\n  - `url`: The URL of the sitemap (required if `sitemap` is included). This can\n    be either an actual URL or a local file.\n  - `find`: A string to search for in sitemap URLs (for example\n    `https://somehere.test`) (required if `replace` is specified).\n  - `replace`: The string to replace the `find` string with (for example\n    `http://localhost:3000`) (required if `find` is specified).\n  - `exclude`: An array of strings with regular expressions to exclude URLs\n    from the sitemap (for example `['\\.pdf$']` to exclude any PDF files). Since\n    these are string representations of regular expressions, the backslash must\n    be escaped (for example `\\\\.`). Exclude is performed before find/replace,\n    so uses the original URLs from the sitemap.\n- `urls`: An array of URLs to be tested, which must contain at least one value.\n  Each array entry can either be a URL string, or an object that contains a\n  `url` string and an optional `settings` object. This object can contain any\n  of the `settings` values identified previously and overrides that setting for\n  testing that URL. The `url` string can be either an actual URL or a local\n  file, as shown in the example below.\n\nThe following shows all available settings, except `sitemap`, with the default\nvalues.\n\n```json\n{\n  \"puppeteerLaunchOptions\": {\n    \"headless\": \"new\"\n  },\n  \"reporters\": [\"cli\", \"html\", \"json\"],\n  \"settings\": {\n    \"brokenLinkTest\": {\n      \"enabled\": true,\n      \"failWarn\": false,\n      \"checkWithBrowser\": false,\n      \"ignoreDuplicates\": true\n    },\n    \"consoleErrorTest\": {\n      \"enabled\": true,\n      \"failWarn\": false\n    },\n    \"consoleOutputTest\": {\n      \"enabled\": true,\n      \"failWarn\": false\n    },\n    \"externalScriptTest\": {\n      \"enabled\": true,\n      \"failWarn\": true\n    },\n    \"horizontalScrollbarTest\": {\n      \"enabled\": true,\n      \"failWarn\": false\n    },\n    \"pageLoadTimeTest\": {\n      \"enabled\": true,\n      \"failWarn\": false,\n      \"pageLoadTimeThreshold\": 2\n    },\n    \"renderedHtmlTest\": {\n      \"enabled\": true,\n      \"failWarn\": false\n    }\n  }\n}\n```\n\nNumerous example config files used in the tests can be found in the\n[test fixtures](tests/fixtures/configs/).\n\n## Container images\n\nProvided with the Pagean project are container images configured to run the\ntests. All available image tags can be found in the\n`registry.gitlab.com/gitlab-ci-utils/pagean`\n[repository](https://gitlab.com/gitlab-ci-utils/pagean/container_registry).\nDetails on each release can be found on the\n[Releases](https://gitlab.com/gitlab-ci-utils/pagean/releases) page.\n\n**Note:** any images in the `gitlab-ci-utils/pagean/tmp` repository are\ntemporary images used during the build process and may be deleted at any point.\n\n### Puppeteer cache location\n\nIn [Puppeteer v19](https://github.com/puppeteer/puppeteer/releases/tag/v19.0.0)\nthe default cache location for installing the Chrome binary was changed from\nwithin the project's `node_modules` folder to `~/.cache/puppeteer`. To simplify\nexecution in a container, the `PUPPETEER_CACHE_DIR` environment variable is set\nto install the Chrome binaries in `/home/pptruser/.cache/puppeteer` during\ncontainer build, so setting to another value before execution can cause errors\nwhere Puppeteer can't find the Chrome binary.\n\n## GitLab CI configuration\n\nThe following is an example job from a .gitlab-ci.yml file to use this image to\nrun Pagean against another project in GitLab CI:\n\n```yaml\npagean:\n  image: registry.gitlab.com/gitlab-ci-utils/pagean:latest\n  stage: test\n  script:\n    - pagean\n  artifacts:\n    when: always\n    paths:\n      - pagean-results.html\n      - pagean-results.json\n      - pagean-external-scripts/\n```\n\n### Testing with a static HTTP server\n\nThe container image shown previously includes\n[`serve`](https://www.npmjs.com/package/serve) and\n[`wait-on`](https://www.npmjs.com/package/wait-on) installed globally to run a\nlocal HTTP server for testing static content. The example job below illustrates\nhow to use this for Pagean tests. The script starts the server in this\nproject's `./tests/fixtures/site` directory and uses `wait-on` to hold the\nscript until the server is running and returns a valid response. The referenced\n`pageanrc` file is the same as the project default `pageanrc`, but references\nall test URLs from the local server.\n\n```yaml\npagean:\n  image: registry.gitlab.com/gitlab-ci-utils/pagean:latest\n  stage: test\n  before_script:\n    # Start static server in test cases directory, discarding any console output,\n    # and wait until the server is running.\n    - serve ./tests/fixtures/site \u003e /dev/null 2\u003e\u00261 \u0026 wait-on http://localhost:3000\n  script:\n    - pagean -c static-server.pageanrc.json\n  artifacts:\n    when: always\n    paths:\n      - pagean-results.html\n      - pagean-results.json\n      - pagean-external-scripts/\n```\n\n## Linting pageanrc files\n\nA command line tool is also available to lint pageanrc files, which is executed\nas follows:\n\n```\nInstalled globally:\n\u003e pageanrc-lint [options] [file] (default: \"./.pageanrc.json\")\n\nInstalled locally:\n\u003e npx pageanrc-lint [options] [file] (default: \"./.pageanrc.json\")\n\nLint a pageanrc file\n\nOptions:\n  -V, --version  output the version number\n  -j, --json     output JSON with full details\n  -h, --help     display help for command\n```\n\nThe `--json` option outputs the JSON results to stdout in all cases for\nconsistency (`[]` if no errors found, so that it always outputs valid\nJSON). Otherwise errors are output to stderr, for example:\n\n```sh\n.\\tests\\test-configs\\cli-tests\\some-test.pageanrc.json\n  \u003cpageanrc\u003e.puppeteerLaunchOptions                  must NOT have fewer than 1 properties\n  \u003cpageanrc\u003e.reporters[0]                            must be equal to one of the allowed values (cli, html, json)\n  \u003cpageanrc\u003e.settings.consoleOutputTest              must be either Boolean or object with the appropriate properties\n  \u003cpageanrc\u003e.settings.pageLoadTimeTest.foo           must NOT contain additional properties: \"foo\"\n  \u003cpageanrc\u003e.settings.pageLoadTimeTest               must be either Boolean or object with the appropriate properties\n  \u003cpageanrc\u003e.sitemap                                 must use 'find' and 'replace' together\n  \u003cpageanrc\u003e.urls[2].settings.consoleOutputTest      must be either Boolean or object with the appropriate properties\n  \u003cpageanrc\u003e.urls[3]                                 must be either URL string or object with the appropriate properties\n  \u003cpageanrc\u003e.urls[5]                                 must have required property 'url'\n```\n\nIn some cases, a single error might result in multiple messages based on the\noptions in the schema definition, especially for cases that can be either a\nsingle value or an object with specific properties (for example the errors for\n`\u003cpageanrc\u003e.settings.pageLoadTimeTest` in the preceding example).\n\nNote that because of the large number of options, which are dependent on an\nexternal project, the linting of `puppeteerLaunchOptions` only checks that at\nleast one property is provided, it doesn't check the detailed settings.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/gitlab.com%2Fgitlab-ci-utils%2Fpagean","html_url":"https://awesome.ecosyste.ms/projects/gitlab.com%2Fgitlab-ci-utils%2Fpagean","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/gitlab.com%2Fgitlab-ci-utils%2Fpagean/lists"}