├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md ├── dependabot.yml └── workflows │ └── build.yml ├── .gitignore ├── .nvmrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── _tpl └── template.html ├── check-version.mjs ├── data ├── known-good-versions-with-downloads.json ├── known-good-versions.json ├── last-known-good-versions-with-downloads.json ├── last-known-good-versions.json ├── latest-patch-versions-per-build-with-downloads.json ├── latest-patch-versions-per-build.json ├── latest-versions-per-milestone-with-downloads.json └── latest-versions-per-milestone.json ├── dist └── .nojekyll ├── find-version.mjs ├── generate-directory-index.mjs ├── generate-extra-json.mjs ├── generate-html.mjs ├── generate-latest-release.mjs ├── html-utils.mjs ├── is-older-version.mjs ├── json-utils.mjs ├── logo.svg ├── package-lock.json ├── package.json └── url-utils.mjs /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = tab 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [{README.md,*.yml}] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | > [!IMPORTANT] 11 | > **This issue tracker tracks bugs with [the Chrome for Testing availability dashboard](https://googlechromelabs.github.io/chrome-for-testing/) and [its API](https://github.com/GoogleChromeLabs/chrome-for-testing#json-api-endpoints).** 12 | > 13 | > - Are you reporting a bug that reproduces in Chrome for Testing but not in Chrome? File it here: https://goo.gle/cftbug 14 | > - Are you reporting a bug in Chrome? File it here: https://crbug.com/new 15 | 16 | **Describe the bug** 17 | A clear and concise description of what the bug is. 18 | 19 | **To reproduce** 20 | Steps to reproduce the behavior: 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "08:00" 8 | timezone: "Europe/Berlin" 9 | open-pull-requests-limit: 2 10 | allow: 11 | - dependency-type: "production" 12 | ignore: 13 | - dependency-name: "devtools-protocol" 14 | groups: 15 | all: 16 | patterns: 17 | - '*' 18 | - package-ecosystem: "github-actions" # Necessary to update action hash 19 | directory: "/" 20 | schedule: 21 | interval: weekly 22 | time: "08:00" 23 | timezone: "Europe/Berlin" 24 | open-pull-requests-limit: 2 25 | groups: 26 | all: 27 | patterns: 28 | - '*' 29 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the “License”); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an “AS IS” BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: 'Build and deploy' 16 | 17 | permissions: 18 | actions: write 19 | attestations: none 20 | checks: write 21 | contents: write 22 | deployments: none 23 | id-token: write 24 | issues: none 25 | discussions: none 26 | packages: none 27 | pages: write 28 | pull-requests: none 29 | repository-projects: write 30 | security-events: none 31 | statuses: none 32 | 33 | on: 34 | schedule: 35 | # Run hourly at xx:05. 36 | - cron: '05 * * * *' 37 | push: 38 | branches: 39 | - main 40 | workflow_dispatch: 41 | 42 | jobs: 43 | build-website: 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 48 | with: 49 | ref: ${{ github.head_ref }} 50 | token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 51 | 52 | - name: Set up Node.js 53 | uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 54 | with: 55 | node-version-file: '.nvmrc' 56 | 57 | - name: Install dependencies 58 | run: npm install 59 | 60 | - name: Build 61 | run: npm run build 62 | 63 | - name: Update last known good versions per channel 64 | run: | 65 | git config user.name 'Chrome for Testing bot' 66 | git config user.email 'mathias+cft@chromium.org' 67 | git add data 68 | git commit data -m 'Update latest available version numbers' || true 69 | git push 70 | 71 | - name: Deploy to gh-pages 72 | uses: JamesIves/github-pages-deploy-action@ec9c88baef04b842ca6f0a132fd61c762aa6c1b0 # v4.6.0 73 | with: 74 | branch: gh-pages 75 | folder: dist 76 | ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} 77 | single-commit: true 78 | git-config-name: Chrome for Testing bot 79 | git-config-email: mathias+cft@chromium.org 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | data/dashboard.json 2 | 3 | dist 4 | 5 | # Installed npm modules 6 | node_modules 7 | 8 | # Folder view configuration files 9 | .DS_Store 10 | Desktop.ini 11 | 12 | # Thumbnail cache files 13 | ._* 14 | Thumbs.db 15 | 16 | # Files that might appear on external disks 17 | .Spotlight-V100 18 | .Trashes 19 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We’d love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow. 4 | 5 | ## Contributor License Agreement 6 | 7 | Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project. Head over to to see your current agreements on file or to sign a new one. 8 | 9 | You generally only need to submit a CLA once, so if you’ve already submitted one (even if it was for a different project), you probably don’t need to do it again. 10 | 11 | ## Code reviews 12 | 13 | All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more information on using pull requests. 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | https://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | https://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chrome for Testing availability 2 | 3 | ![](logo.svg) 4 | 5 | ## JSON API endpoints 6 | 7 | | Endpoint | Description | 8 | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | 9 | | [`known-good-versions.json`](https://googlechromelabs.github.io/chrome-for-testing/known-good-versions.json) | The versions for which all CfT assets are available for download. Useful for bisecting. | 10 | | [`known-good-versions-with-downloads.json`](https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json) | Same as above, but with an extra `downloads` property for each version, listing the full download URLs per asset. | 11 | | [`last-known-good-versions.json`](https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json) | The latest versions for which all CfT assets are available for download, for each Chrome release channel (Stable/Beta/Dev/Canary). | 12 | | [`last-known-good-versions-with-downloads.json`](https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json) | Same as above, but with an extra `downloads` property for each channel, listing the full download URLs per asset. | 13 | | [`latest-patch-versions-per-build.json`](https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build.json) | The latest versions for which all CfT assets are available for download, for each known combination of `MAJOR.MINOR.BUILD` versions. | 14 | | [`latest-patch-versions-per-build-with-downloads.json`](https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build-with-downloads.json) | Same as above, but with an extra `downloads` property for each version, listing the full download URLs per asset. | 15 | | [`latest-versions-per-milestone.json`](https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone.json) | The latest versions for which all CfT assets are available for download, for each Chrome milestone. | 16 | | [`latest-versions-per-milestone-with-downloads.json`](https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone-with-downloads.json) | Same as above, but with an extra `downloads` property for each milestone, listing the full download URLs per asset. | 17 | 18 | The set of “all CfT assets” for a given Chrome version is a matrix of supported [binaries](#supported-binaries) × [platforms](#supported-platforms). 19 | 20 | ### Supported binaries 21 | 22 | The current list of supported binaries is: 23 | 24 | - `chrome` a.k.a. Chrome for Testing (supported since v113.0.5672.0) 25 | - `chromedriver` (supported since v115.0.5763.0) 26 | - `chrome-headless-shell` (supported since v120.0.6098.0) 27 | 28 | ### Supported platforms 29 | 30 | The current list of supported platforms is: 31 | 32 | - `linux64` 33 | - `mac-arm64` 34 | - `mac-x64` 35 | - `win32` 36 | - `win64` 37 | 38 | ## Other API endpoints 39 | 40 | For historical reasons, `LATEST_RELEASE_` files containing fully qualified version numbers are available as well. 41 | 42 | 1. E.g. [`https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116`](https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116) answers the question “what’s the latest available version within milestone 116?”. 43 | 1. E.g. [`https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116.0.5845`](https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_116.0.5845) answers the question “what’s the latest available version within the 116.0.5845.* range?”. 44 | 1. E.g. [`https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE`](https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE) answers the question “what’s the latest available Stable channel version?”. Similar for the other channels (`BETA`/`DEV`/`CANARY`). 45 | 46 | These can be used instead of the `latest-versions-per-milestone`, `latest-patch-versions-per-build`, and `last-known-good-versions` [JSON API endpoints](#json-api-endpoints) respectively. 47 | 48 | Additionally, each version from the [`known-good-versions-with-downloads.json`](https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json) is published as a separate JSON file containing its download URLs — for example, [`123.0.6309.0.json`](https://googlechromelabs.github.io/chrome-for-testing/123.0.6309.0.json). 49 | 50 | You can [browse the complete list of JSON and text files](https://googlechromelabs.github.io/chrome-for-testing/files). 51 | 52 | ## CLI utilities 53 | 54 | ### Find the latest Chrome versions across channels 55 | 56 | ``` 57 | $ npm run find 58 | 59 | > find 60 | > node --no-warnings find-version.mjs 61 | 62 | Checking the Stable channel… 63 | Found versions: Set(2) { '113.0.5672.93', '113.0.5672.92' } 64 | Recommended version for Stable channel: 113.0.5672.92 65 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/linux64/chrome-linux64.zip 404 66 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/mac-arm64/chrome-mac-arm64.zip 404 67 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/mac-x64/chrome-mac-x64.zip 404 68 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/win32/chrome-win32.zip 404 69 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/win64/chrome-win64.zip 404 70 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/linux64/chromedriver-linux64.zip 404 71 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/mac-arm64/chromedriver-mac-arm64.zip 404 72 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/mac-x64/chromedriver-mac-x64.zip 404 73 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/win32/chromedriver-win32.zip 404 74 | https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.92/win64/chromedriver-win64.zip 404 75 | ❌ NOT OK 76 | 77 | Checking the Beta channel… 78 | Found versions: Set(1) { '114.0.5735.26' } 79 | Recommended version for Beta channel: 114.0.5735.26 80 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/linux64/chrome-linux64.zip 200 81 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/mac-arm64/chrome-mac-arm64.zip 200 82 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/mac-x64/chrome-mac-x64.zip 200 83 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/win32/chrome-win32.zip 200 84 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/win64/chrome-win64.zip 200 85 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/linux64/chromedriver-linux64.zip 404 86 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/mac-arm64/chromedriver-mac-arm64.zip 404 87 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/mac-x64/chromedriver-mac-x64.zip 404 88 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/win32/chromedriver-win32.zip 404 89 | https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.26/win64/chromedriver-win64.zip 404 90 | ✅ OK 91 | 92 | Checking the Dev channel… 93 | Found versions: Set(1) { '115.0.5762.4' } 94 | Recommended version for Dev channel: 115.0.5762.4 95 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/linux64/chrome-linux64.zip 200 96 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/mac-arm64/chrome-mac-arm64.zip 200 97 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/mac-x64/chrome-mac-x64.zip 200 98 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/win32/chrome-win32.zip 200 99 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/win64/chrome-win64.zip 200 100 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/linux64/chromedriver-linux64.zip 200 101 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/mac-arm64/chromedriver-mac-arm64.zip 200 102 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/mac-x64/chromedriver-mac-x64.zip 200 103 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/win32/chromedriver-win32.zip 200 104 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5762.4/win64/chromedriver-win64.zip 200 105 | ✅ OK 106 | 107 | Checking the Canary channel… 108 | Found versions: Set(2) { '115.0.5765.0', '115.0.5763.0' } 109 | Recommended version for Canary channel: 115.0.5763.0 110 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/linux64/chrome-linux64.zip 200 111 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/mac-arm64/chrome-mac-arm64.zip 200 112 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/mac-x64/chrome-mac-x64.zip 200 113 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/win32/chrome-win32.zip 200 114 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/win64/chrome-win64.zip 200 115 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/linux64/chromedriver-linux64.zip 200 116 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/mac-arm64/chromedriver-mac-arm64.zip 200 117 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/mac-x64/chromedriver-mac-x64.zip 200 118 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/win32/chromedriver-win32.zip 200 119 | https://storage.googleapis.com/chrome-for-testing-public/115.0.5763.0/win64/chromedriver-win64.zip 200 120 | ✅ OK 121 | ``` 122 | 123 | ### Check a specific Chrome version for CfT binary availability 124 | 125 | ``` 126 | $ npm run check 118.0.5962.0 127 | 128 | > check 129 | > node --no-warnings check-version.mjs "118.0.5962.0" 130 | 131 | Checking downloads for v118.0.5962.0… 132 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/linux64/chrome-linux64.zip 200 133 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/mac-arm64/chrome-mac-arm64.zip 200 134 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/mac-x64/chrome-mac-x64.zip 200 135 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/win32/chrome-win32.zip 200 136 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/win64/chrome-win64.zip 200 137 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/linux64/chromedriver-linux64.zip 200 138 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/mac-arm64/chromedriver-mac-arm64.zip 200 139 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/mac-x64/chromedriver-mac-x64.zip 200 140 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/win32/chromedriver-win32.zip 200 141 | https://storage.googleapis.com/chrome-for-testing-public/118.0.5962.0/win64/chromedriver-win64.zip 200 142 | ✅ OK 143 | ``` 144 | 145 | ## FAQ 146 | 147 | ### What is Chrome for Testing? 148 | 149 | Chrome for Testing is a new Chrome flavor that specifically targets web app testing and automation use cases. Read [_Chrome for Testing: reliable downloads for browser automation_](https://developer.chrome.com/blog/chrome-for-testing/) for more details. 150 | 151 | ### What’s the easiest way to download Chrome for Testing binaries? 152 | 153 | Use [`@puppeteer/browsers`](https://pptr.dev/browsers-api/). 154 | 155 | ### How to install the system-level dependencies required for archived `linux64` binaries? 156 | 157 | ```sh 158 | unzip chrome-linux64.zip; 159 | apt update; 160 | while read pkg; do 161 | apt-get satisfy -y --no-install-recommends "${pkg}"; 162 | done < chrome-linux64/deb.deps; 163 | ``` 164 | 165 | ### macOS says the `*.app` is damaged. What now? 166 | 167 | On macOS, if you download a Chrome for Testing ZIP file _using a browser_ instead of via [`@puppeteer/browsers`](https://pptr.dev/browsers-api/), `curl`, or `wget`, you might get this warning: 168 | 169 | > “Google Chrome for Testing.app” is damaged and can’t be opened. You should move it to the Trash. 170 | 171 | This happens because macOS [Gatekeeper](https://support.apple.com/guide/security/gatekeeper-and-runtime-protection-sec5599b66df/web) sets an extended attribute that marks the ZIP file and any files within it as “downloaded via a browser” and thus potentially dangerous. 172 | 173 | To fix the problem, recursively remove the extended attribute: 174 | 175 | ```sh 176 | xattr -cr 'Google Chrome for Testing.app' 177 | ``` 178 | 179 | ## Support 180 | 181 | - For bug reports with the CfT dashboard and/or API (i.e. the code in this repository): [file an issue](https://github.com/GoogleChromeLabs/chrome-for-testing/issues) 182 | - For bug reports with any of the CfT binaries: File an issue for [Headless](https://goo.gle/headless-bug), [ChromeDriver](https://crbug.com/chromedriver/new), [CfT](https://goo.gle/cftbug), or https://crbug.com/new for anything else 183 | - For questions: Stack Overflow (unofficial), use the [`chrome-for-testing`](https://stackoverflow.com/questions/tagged/chrome-for-testing) tag 184 | -------------------------------------------------------------------------------- /_tpl/template.html: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | Chrome for Testing availability 20 | 21 | 42 | 43 |

Chrome for Testing availability

44 |

This page lists the latest available cross-platform Chrome for Testing versions and assets per Chrome release channel.

45 |

Consult our JSON API endpoints if you’re looking to build automated scripts based on Chrome for Testing release data.

46 |

Last updated @

47 | %%%DATA%%% 48 | 60 | -------------------------------------------------------------------------------- /check-version.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This script gets Chrome release version numbers per platform 18 | // from the Chromium Dash API, and then prints the corresponding 19 | // Chrome for Testing download URLs + their HTTP status codes. 20 | 21 | import {checkDownloadsForVersion} from './url-utils.mjs'; 22 | 23 | const checkVersion = async (version = '123.0.6309.0') => { 24 | console.log(`Checking downloads for v${version}…`); 25 | const checked = await checkDownloadsForVersion(version); 26 | for (const {url, status} of checked.downloads) { 27 | console.log(url, status); 28 | } 29 | console.log(checked.isOk ? '\u2705 OK' : '\u274C NOT OK'); 30 | }; 31 | 32 | const version = process.argv[2] || '123.0.6309.0'; 33 | await checkVersion(version); 34 | -------------------------------------------------------------------------------- /data/last-known-good-versions-with-downloads.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "2025-06-08T12:12:37.854Z", 3 | "channels": { 4 | "Stable": { 5 | "channel": "Stable", 6 | "version": "137.0.7151.68", 7 | "revision": "1453031", 8 | "downloads": { 9 | "chrome": [ 10 | { 11 | "platform": "linux64", 12 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/linux64/chrome-linux64.zip" 13 | }, 14 | { 15 | "platform": "mac-arm64", 16 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-arm64/chrome-mac-arm64.zip" 17 | }, 18 | { 19 | "platform": "mac-x64", 20 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-x64/chrome-mac-x64.zip" 21 | }, 22 | { 23 | "platform": "win32", 24 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win32/chrome-win32.zip" 25 | }, 26 | { 27 | "platform": "win64", 28 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win64/chrome-win64.zip" 29 | } 30 | ], 31 | "chromedriver": [ 32 | { 33 | "platform": "linux64", 34 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/linux64/chromedriver-linux64.zip" 35 | }, 36 | { 37 | "platform": "mac-arm64", 38 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-arm64/chromedriver-mac-arm64.zip" 39 | }, 40 | { 41 | "platform": "mac-x64", 42 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-x64/chromedriver-mac-x64.zip" 43 | }, 44 | { 45 | "platform": "win32", 46 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win32/chromedriver-win32.zip" 47 | }, 48 | { 49 | "platform": "win64", 50 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win64/chromedriver-win64.zip" 51 | } 52 | ], 53 | "chrome-headless-shell": [ 54 | { 55 | "platform": "linux64", 56 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/linux64/chrome-headless-shell-linux64.zip" 57 | }, 58 | { 59 | "platform": "mac-arm64", 60 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-arm64/chrome-headless-shell-mac-arm64.zip" 61 | }, 62 | { 63 | "platform": "mac-x64", 64 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-x64/chrome-headless-shell-mac-x64.zip" 65 | }, 66 | { 67 | "platform": "win32", 68 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win32/chrome-headless-shell-win32.zip" 69 | }, 70 | { 71 | "platform": "win64", 72 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win64/chrome-headless-shell-win64.zip" 73 | } 74 | ] 75 | } 76 | }, 77 | "Beta": { 78 | "channel": "Beta", 79 | "version": "138.0.7204.15", 80 | "revision": "1465706", 81 | "downloads": { 82 | "chrome": [ 83 | { 84 | "platform": "linux64", 85 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/linux64/chrome-linux64.zip" 86 | }, 87 | { 88 | "platform": "mac-arm64", 89 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-arm64/chrome-mac-arm64.zip" 90 | }, 91 | { 92 | "platform": "mac-x64", 93 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-x64/chrome-mac-x64.zip" 94 | }, 95 | { 96 | "platform": "win32", 97 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win32/chrome-win32.zip" 98 | }, 99 | { 100 | "platform": "win64", 101 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win64/chrome-win64.zip" 102 | } 103 | ], 104 | "chromedriver": [ 105 | { 106 | "platform": "linux64", 107 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/linux64/chromedriver-linux64.zip" 108 | }, 109 | { 110 | "platform": "mac-arm64", 111 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-arm64/chromedriver-mac-arm64.zip" 112 | }, 113 | { 114 | "platform": "mac-x64", 115 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-x64/chromedriver-mac-x64.zip" 116 | }, 117 | { 118 | "platform": "win32", 119 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win32/chromedriver-win32.zip" 120 | }, 121 | { 122 | "platform": "win64", 123 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win64/chromedriver-win64.zip" 124 | } 125 | ], 126 | "chrome-headless-shell": [ 127 | { 128 | "platform": "linux64", 129 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/linux64/chrome-headless-shell-linux64.zip" 130 | }, 131 | { 132 | "platform": "mac-arm64", 133 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-arm64/chrome-headless-shell-mac-arm64.zip" 134 | }, 135 | { 136 | "platform": "mac-x64", 137 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-x64/chrome-headless-shell-mac-x64.zip" 138 | }, 139 | { 140 | "platform": "win32", 141 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win32/chrome-headless-shell-win32.zip" 142 | }, 143 | { 144 | "platform": "win64", 145 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win64/chrome-headless-shell-win64.zip" 146 | } 147 | ] 148 | } 149 | }, 150 | "Dev": { 151 | "channel": "Dev", 152 | "version": "139.0.7219.3", 153 | "revision": "1468830", 154 | "downloads": { 155 | "chrome": [ 156 | { 157 | "platform": "linux64", 158 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/linux64/chrome-linux64.zip" 159 | }, 160 | { 161 | "platform": "mac-arm64", 162 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/mac-arm64/chrome-mac-arm64.zip" 163 | }, 164 | { 165 | "platform": "mac-x64", 166 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/mac-x64/chrome-mac-x64.zip" 167 | }, 168 | { 169 | "platform": "win32", 170 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/win32/chrome-win32.zip" 171 | }, 172 | { 173 | "platform": "win64", 174 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/win64/chrome-win64.zip" 175 | } 176 | ], 177 | "chromedriver": [ 178 | { 179 | "platform": "linux64", 180 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/linux64/chromedriver-linux64.zip" 181 | }, 182 | { 183 | "platform": "mac-arm64", 184 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/mac-arm64/chromedriver-mac-arm64.zip" 185 | }, 186 | { 187 | "platform": "mac-x64", 188 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/mac-x64/chromedriver-mac-x64.zip" 189 | }, 190 | { 191 | "platform": "win32", 192 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/win32/chromedriver-win32.zip" 193 | }, 194 | { 195 | "platform": "win64", 196 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/win64/chromedriver-win64.zip" 197 | } 198 | ], 199 | "chrome-headless-shell": [ 200 | { 201 | "platform": "linux64", 202 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/linux64/chrome-headless-shell-linux64.zip" 203 | }, 204 | { 205 | "platform": "mac-arm64", 206 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/mac-arm64/chrome-headless-shell-mac-arm64.zip" 207 | }, 208 | { 209 | "platform": "mac-x64", 210 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/mac-x64/chrome-headless-shell-mac-x64.zip" 211 | }, 212 | { 213 | "platform": "win32", 214 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/win32/chrome-headless-shell-win32.zip" 215 | }, 216 | { 217 | "platform": "win64", 218 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7219.3/win64/chrome-headless-shell-win64.zip" 219 | } 220 | ] 221 | } 222 | }, 223 | "Canary": { 224 | "channel": "Canary", 225 | "version": "139.0.7226.0", 226 | "revision": "1470985", 227 | "downloads": { 228 | "chrome": [ 229 | { 230 | "platform": "linux64", 231 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/linux64/chrome-linux64.zip" 232 | }, 233 | { 234 | "platform": "mac-arm64", 235 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-arm64/chrome-mac-arm64.zip" 236 | }, 237 | { 238 | "platform": "mac-x64", 239 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-x64/chrome-mac-x64.zip" 240 | }, 241 | { 242 | "platform": "win32", 243 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win32/chrome-win32.zip" 244 | }, 245 | { 246 | "platform": "win64", 247 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win64/chrome-win64.zip" 248 | } 249 | ], 250 | "chromedriver": [ 251 | { 252 | "platform": "linux64", 253 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/linux64/chromedriver-linux64.zip" 254 | }, 255 | { 256 | "platform": "mac-arm64", 257 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-arm64/chromedriver-mac-arm64.zip" 258 | }, 259 | { 260 | "platform": "mac-x64", 261 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-x64/chromedriver-mac-x64.zip" 262 | }, 263 | { 264 | "platform": "win32", 265 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win32/chromedriver-win32.zip" 266 | }, 267 | { 268 | "platform": "win64", 269 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win64/chromedriver-win64.zip" 270 | } 271 | ], 272 | "chrome-headless-shell": [ 273 | { 274 | "platform": "linux64", 275 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/linux64/chrome-headless-shell-linux64.zip" 276 | }, 277 | { 278 | "platform": "mac-arm64", 279 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" 280 | }, 281 | { 282 | "platform": "mac-x64", 283 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-x64/chrome-headless-shell-mac-x64.zip" 284 | }, 285 | { 286 | "platform": "win32", 287 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win32/chrome-headless-shell-win32.zip" 288 | }, 289 | { 290 | "platform": "win64", 291 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win64/chrome-headless-shell-win64.zip" 292 | } 293 | ] 294 | } 295 | } 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /data/last-known-good-versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "2025-06-08T12:12:37.854Z", 3 | "channels": { 4 | "Stable": { 5 | "channel": "Stable", 6 | "version": "137.0.7151.68", 7 | "revision": "1453031" 8 | }, 9 | "Beta": { 10 | "channel": "Beta", 11 | "version": "138.0.7204.15", 12 | "revision": "1465706" 13 | }, 14 | "Dev": { 15 | "channel": "Dev", 16 | "version": "139.0.7219.3", 17 | "revision": "1468830" 18 | }, 19 | "Canary": { 20 | "channel": "Canary", 21 | "version": "139.0.7226.0", 22 | "revision": "1470985" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /data/latest-versions-per-milestone-with-downloads.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "2025-06-08T12:12:37.857Z", 3 | "milestones": { 4 | "113": { 5 | "milestone": "113", 6 | "version": "113.0.5672.63", 7 | "revision": "1121455", 8 | "downloads": { 9 | "chrome": [ 10 | { 11 | "platform": "linux64", 12 | "url": "https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.63/linux64/chrome-linux64.zip" 13 | }, 14 | { 15 | "platform": "mac-arm64", 16 | "url": "https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.63/mac-arm64/chrome-mac-arm64.zip" 17 | }, 18 | { 19 | "platform": "mac-x64", 20 | "url": "https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.63/mac-x64/chrome-mac-x64.zip" 21 | }, 22 | { 23 | "platform": "win32", 24 | "url": "https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.63/win32/chrome-win32.zip" 25 | }, 26 | { 27 | "platform": "win64", 28 | "url": "https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.63/win64/chrome-win64.zip" 29 | } 30 | ] 31 | } 32 | }, 33 | "114": { 34 | "milestone": "114", 35 | "version": "114.0.5735.133", 36 | "revision": "1135570", 37 | "downloads": { 38 | "chrome": [ 39 | { 40 | "platform": "linux64", 41 | "url": "https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.133/linux64/chrome-linux64.zip" 42 | }, 43 | { 44 | "platform": "mac-arm64", 45 | "url": "https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.133/mac-arm64/chrome-mac-arm64.zip" 46 | }, 47 | { 48 | "platform": "mac-x64", 49 | "url": "https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.133/mac-x64/chrome-mac-x64.zip" 50 | }, 51 | { 52 | "platform": "win32", 53 | "url": "https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.133/win32/chrome-win32.zip" 54 | }, 55 | { 56 | "platform": "win64", 57 | "url": "https://storage.googleapis.com/chrome-for-testing-public/114.0.5735.133/win64/chrome-win64.zip" 58 | } 59 | ] 60 | } 61 | }, 62 | "115": { 63 | "milestone": "115", 64 | "version": "115.0.5790.170", 65 | "revision": "1148114", 66 | "downloads": { 67 | "chrome": [ 68 | { 69 | "platform": "linux64", 70 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/linux64/chrome-linux64.zip" 71 | }, 72 | { 73 | "platform": "mac-arm64", 74 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/mac-arm64/chrome-mac-arm64.zip" 75 | }, 76 | { 77 | "platform": "mac-x64", 78 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/mac-x64/chrome-mac-x64.zip" 79 | }, 80 | { 81 | "platform": "win32", 82 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/win32/chrome-win32.zip" 83 | }, 84 | { 85 | "platform": "win64", 86 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/win64/chrome-win64.zip" 87 | } 88 | ], 89 | "chromedriver": [ 90 | { 91 | "platform": "linux64", 92 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/linux64/chromedriver-linux64.zip" 93 | }, 94 | { 95 | "platform": "mac-arm64", 96 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/mac-arm64/chromedriver-mac-arm64.zip" 97 | }, 98 | { 99 | "platform": "mac-x64", 100 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/mac-x64/chromedriver-mac-x64.zip" 101 | }, 102 | { 103 | "platform": "win32", 104 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/win32/chromedriver-win32.zip" 105 | }, 106 | { 107 | "platform": "win64", 108 | "url": "https://storage.googleapis.com/chrome-for-testing-public/115.0.5790.170/win64/chromedriver-win64.zip" 109 | } 110 | ] 111 | } 112 | }, 113 | "116": { 114 | "milestone": "116", 115 | "version": "116.0.5845.96", 116 | "revision": "1160321", 117 | "downloads": { 118 | "chrome": [ 119 | { 120 | "platform": "linux64", 121 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/linux64/chrome-linux64.zip" 122 | }, 123 | { 124 | "platform": "mac-arm64", 125 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/mac-arm64/chrome-mac-arm64.zip" 126 | }, 127 | { 128 | "platform": "mac-x64", 129 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/mac-x64/chrome-mac-x64.zip" 130 | }, 131 | { 132 | "platform": "win32", 133 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/win32/chrome-win32.zip" 134 | }, 135 | { 136 | "platform": "win64", 137 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/win64/chrome-win64.zip" 138 | } 139 | ], 140 | "chromedriver": [ 141 | { 142 | "platform": "linux64", 143 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/linux64/chromedriver-linux64.zip" 144 | }, 145 | { 146 | "platform": "mac-arm64", 147 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/mac-arm64/chromedriver-mac-arm64.zip" 148 | }, 149 | { 150 | "platform": "mac-x64", 151 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/mac-x64/chromedriver-mac-x64.zip" 152 | }, 153 | { 154 | "platform": "win32", 155 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/win32/chromedriver-win32.zip" 156 | }, 157 | { 158 | "platform": "win64", 159 | "url": "https://storage.googleapis.com/chrome-for-testing-public/116.0.5845.96/win64/chromedriver-win64.zip" 160 | } 161 | ] 162 | } 163 | }, 164 | "117": { 165 | "milestone": "117", 166 | "version": "117.0.5938.149", 167 | "revision": "1181205", 168 | "downloads": { 169 | "chrome": [ 170 | { 171 | "platform": "linux64", 172 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/linux64/chrome-linux64.zip" 173 | }, 174 | { 175 | "platform": "mac-arm64", 176 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/mac-arm64/chrome-mac-arm64.zip" 177 | }, 178 | { 179 | "platform": "mac-x64", 180 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/mac-x64/chrome-mac-x64.zip" 181 | }, 182 | { 183 | "platform": "win32", 184 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/win32/chrome-win32.zip" 185 | }, 186 | { 187 | "platform": "win64", 188 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/win64/chrome-win64.zip" 189 | } 190 | ], 191 | "chromedriver": [ 192 | { 193 | "platform": "linux64", 194 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/linux64/chromedriver-linux64.zip" 195 | }, 196 | { 197 | "platform": "mac-arm64", 198 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/mac-arm64/chromedriver-mac-arm64.zip" 199 | }, 200 | { 201 | "platform": "mac-x64", 202 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/mac-x64/chromedriver-mac-x64.zip" 203 | }, 204 | { 205 | "platform": "win32", 206 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/win32/chromedriver-win32.zip" 207 | }, 208 | { 209 | "platform": "win64", 210 | "url": "https://storage.googleapis.com/chrome-for-testing-public/117.0.5938.149/win64/chromedriver-win64.zip" 211 | } 212 | ] 213 | } 214 | }, 215 | "118": { 216 | "milestone": "118", 217 | "version": "118.0.5993.70", 218 | "revision": "1192594", 219 | "downloads": { 220 | "chrome": [ 221 | { 222 | "platform": "linux64", 223 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/linux64/chrome-linux64.zip" 224 | }, 225 | { 226 | "platform": "mac-arm64", 227 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/mac-arm64/chrome-mac-arm64.zip" 228 | }, 229 | { 230 | "platform": "mac-x64", 231 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/mac-x64/chrome-mac-x64.zip" 232 | }, 233 | { 234 | "platform": "win32", 235 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/win32/chrome-win32.zip" 236 | }, 237 | { 238 | "platform": "win64", 239 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/win64/chrome-win64.zip" 240 | } 241 | ], 242 | "chromedriver": [ 243 | { 244 | "platform": "linux64", 245 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/linux64/chromedriver-linux64.zip" 246 | }, 247 | { 248 | "platform": "mac-arm64", 249 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/mac-arm64/chromedriver-mac-arm64.zip" 250 | }, 251 | { 252 | "platform": "mac-x64", 253 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/mac-x64/chromedriver-mac-x64.zip" 254 | }, 255 | { 256 | "platform": "win32", 257 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/win32/chromedriver-win32.zip" 258 | }, 259 | { 260 | "platform": "win64", 261 | "url": "https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/win64/chromedriver-win64.zip" 262 | } 263 | ] 264 | } 265 | }, 266 | "119": { 267 | "milestone": "119", 268 | "version": "119.0.6045.105", 269 | "revision": "1204232", 270 | "downloads": { 271 | "chrome": [ 272 | { 273 | "platform": "linux64", 274 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/linux64/chrome-linux64.zip" 275 | }, 276 | { 277 | "platform": "mac-arm64", 278 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/mac-arm64/chrome-mac-arm64.zip" 279 | }, 280 | { 281 | "platform": "mac-x64", 282 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/mac-x64/chrome-mac-x64.zip" 283 | }, 284 | { 285 | "platform": "win32", 286 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/win32/chrome-win32.zip" 287 | }, 288 | { 289 | "platform": "win64", 290 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/win64/chrome-win64.zip" 291 | } 292 | ], 293 | "chromedriver": [ 294 | { 295 | "platform": "linux64", 296 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/linux64/chromedriver-linux64.zip" 297 | }, 298 | { 299 | "platform": "mac-arm64", 300 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/mac-arm64/chromedriver-mac-arm64.zip" 301 | }, 302 | { 303 | "platform": "mac-x64", 304 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/mac-x64/chromedriver-mac-x64.zip" 305 | }, 306 | { 307 | "platform": "win32", 308 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/win32/chromedriver-win32.zip" 309 | }, 310 | { 311 | "platform": "win64", 312 | "url": "https://storage.googleapis.com/chrome-for-testing-public/119.0.6045.105/win64/chromedriver-win64.zip" 313 | } 314 | ] 315 | } 316 | }, 317 | "120": { 318 | "milestone": "120", 319 | "version": "120.0.6099.109", 320 | "revision": "1217362", 321 | "downloads": { 322 | "chrome": [ 323 | { 324 | "platform": "linux64", 325 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/linux64/chrome-linux64.zip" 326 | }, 327 | { 328 | "platform": "mac-arm64", 329 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/mac-arm64/chrome-mac-arm64.zip" 330 | }, 331 | { 332 | "platform": "mac-x64", 333 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/mac-x64/chrome-mac-x64.zip" 334 | }, 335 | { 336 | "platform": "win32", 337 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win32/chrome-win32.zip" 338 | }, 339 | { 340 | "platform": "win64", 341 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win64/chrome-win64.zip" 342 | } 343 | ], 344 | "chromedriver": [ 345 | { 346 | "platform": "linux64", 347 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/linux64/chromedriver-linux64.zip" 348 | }, 349 | { 350 | "platform": "mac-arm64", 351 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/mac-arm64/chromedriver-mac-arm64.zip" 352 | }, 353 | { 354 | "platform": "mac-x64", 355 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/mac-x64/chromedriver-mac-x64.zip" 356 | }, 357 | { 358 | "platform": "win32", 359 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win32/chromedriver-win32.zip" 360 | }, 361 | { 362 | "platform": "win64", 363 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win64/chromedriver-win64.zip" 364 | } 365 | ], 366 | "chrome-headless-shell": [ 367 | { 368 | "platform": "linux64", 369 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/linux64/chrome-headless-shell-linux64.zip" 370 | }, 371 | { 372 | "platform": "mac-arm64", 373 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/mac-arm64/chrome-headless-shell-mac-arm64.zip" 374 | }, 375 | { 376 | "platform": "mac-x64", 377 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/mac-x64/chrome-headless-shell-mac-x64.zip" 378 | }, 379 | { 380 | "platform": "win32", 381 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win32/chrome-headless-shell-win32.zip" 382 | }, 383 | { 384 | "platform": "win64", 385 | "url": "https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win64/chrome-headless-shell-win64.zip" 386 | } 387 | ] 388 | } 389 | }, 390 | "121": { 391 | "milestone": "121", 392 | "version": "121.0.6167.184", 393 | "revision": "1233107", 394 | "downloads": { 395 | "chrome": [ 396 | { 397 | "platform": "linux64", 398 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/linux64/chrome-linux64.zip" 399 | }, 400 | { 401 | "platform": "mac-arm64", 402 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/mac-arm64/chrome-mac-arm64.zip" 403 | }, 404 | { 405 | "platform": "mac-x64", 406 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/mac-x64/chrome-mac-x64.zip" 407 | }, 408 | { 409 | "platform": "win32", 410 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/win32/chrome-win32.zip" 411 | }, 412 | { 413 | "platform": "win64", 414 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/win64/chrome-win64.zip" 415 | } 416 | ], 417 | "chromedriver": [ 418 | { 419 | "platform": "linux64", 420 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/linux64/chromedriver-linux64.zip" 421 | }, 422 | { 423 | "platform": "mac-arm64", 424 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/mac-arm64/chromedriver-mac-arm64.zip" 425 | }, 426 | { 427 | "platform": "mac-x64", 428 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/mac-x64/chromedriver-mac-x64.zip" 429 | }, 430 | { 431 | "platform": "win32", 432 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/win32/chromedriver-win32.zip" 433 | }, 434 | { 435 | "platform": "win64", 436 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/win64/chromedriver-win64.zip" 437 | } 438 | ], 439 | "chrome-headless-shell": [ 440 | { 441 | "platform": "linux64", 442 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/linux64/chrome-headless-shell-linux64.zip" 443 | }, 444 | { 445 | "platform": "mac-arm64", 446 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/mac-arm64/chrome-headless-shell-mac-arm64.zip" 447 | }, 448 | { 449 | "platform": "mac-x64", 450 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/mac-x64/chrome-headless-shell-mac-x64.zip" 451 | }, 452 | { 453 | "platform": "win32", 454 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/win32/chrome-headless-shell-win32.zip" 455 | }, 456 | { 457 | "platform": "win64", 458 | "url": "https://storage.googleapis.com/chrome-for-testing-public/121.0.6167.184/win64/chrome-headless-shell-win64.zip" 459 | } 460 | ] 461 | } 462 | }, 463 | "122": { 464 | "milestone": "122", 465 | "version": "122.0.6261.128", 466 | "revision": "1250580", 467 | "downloads": { 468 | "chrome": [ 469 | { 470 | "platform": "linux64", 471 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/linux64/chrome-linux64.zip" 472 | }, 473 | { 474 | "platform": "mac-arm64", 475 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/mac-arm64/chrome-mac-arm64.zip" 476 | }, 477 | { 478 | "platform": "mac-x64", 479 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/mac-x64/chrome-mac-x64.zip" 480 | }, 481 | { 482 | "platform": "win32", 483 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/win32/chrome-win32.zip" 484 | }, 485 | { 486 | "platform": "win64", 487 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/win64/chrome-win64.zip" 488 | } 489 | ], 490 | "chromedriver": [ 491 | { 492 | "platform": "linux64", 493 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/linux64/chromedriver-linux64.zip" 494 | }, 495 | { 496 | "platform": "mac-arm64", 497 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/mac-arm64/chromedriver-mac-arm64.zip" 498 | }, 499 | { 500 | "platform": "mac-x64", 501 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/mac-x64/chromedriver-mac-x64.zip" 502 | }, 503 | { 504 | "platform": "win32", 505 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/win32/chromedriver-win32.zip" 506 | }, 507 | { 508 | "platform": "win64", 509 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/win64/chromedriver-win64.zip" 510 | } 511 | ], 512 | "chrome-headless-shell": [ 513 | { 514 | "platform": "linux64", 515 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/linux64/chrome-headless-shell-linux64.zip" 516 | }, 517 | { 518 | "platform": "mac-arm64", 519 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/mac-arm64/chrome-headless-shell-mac-arm64.zip" 520 | }, 521 | { 522 | "platform": "mac-x64", 523 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/mac-x64/chrome-headless-shell-mac-x64.zip" 524 | }, 525 | { 526 | "platform": "win32", 527 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/win32/chrome-headless-shell-win32.zip" 528 | }, 529 | { 530 | "platform": "win64", 531 | "url": "https://storage.googleapis.com/chrome-for-testing-public/122.0.6261.128/win64/chrome-headless-shell-win64.zip" 532 | } 533 | ] 534 | } 535 | }, 536 | "123": { 537 | "milestone": "123", 538 | "version": "123.0.6312.122", 539 | "revision": "1262506", 540 | "downloads": { 541 | "chrome": [ 542 | { 543 | "platform": "linux64", 544 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/linux64/chrome-linux64.zip" 545 | }, 546 | { 547 | "platform": "mac-arm64", 548 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/mac-arm64/chrome-mac-arm64.zip" 549 | }, 550 | { 551 | "platform": "mac-x64", 552 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/mac-x64/chrome-mac-x64.zip" 553 | }, 554 | { 555 | "platform": "win32", 556 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/win32/chrome-win32.zip" 557 | }, 558 | { 559 | "platform": "win64", 560 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/win64/chrome-win64.zip" 561 | } 562 | ], 563 | "chromedriver": [ 564 | { 565 | "platform": "linux64", 566 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/linux64/chromedriver-linux64.zip" 567 | }, 568 | { 569 | "platform": "mac-arm64", 570 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/mac-arm64/chromedriver-mac-arm64.zip" 571 | }, 572 | { 573 | "platform": "mac-x64", 574 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/mac-x64/chromedriver-mac-x64.zip" 575 | }, 576 | { 577 | "platform": "win32", 578 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/win32/chromedriver-win32.zip" 579 | }, 580 | { 581 | "platform": "win64", 582 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/win64/chromedriver-win64.zip" 583 | } 584 | ], 585 | "chrome-headless-shell": [ 586 | { 587 | "platform": "linux64", 588 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/linux64/chrome-headless-shell-linux64.zip" 589 | }, 590 | { 591 | "platform": "mac-arm64", 592 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/mac-arm64/chrome-headless-shell-mac-arm64.zip" 593 | }, 594 | { 595 | "platform": "mac-x64", 596 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/mac-x64/chrome-headless-shell-mac-x64.zip" 597 | }, 598 | { 599 | "platform": "win32", 600 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/win32/chrome-headless-shell-win32.zip" 601 | }, 602 | { 603 | "platform": "win64", 604 | "url": "https://storage.googleapis.com/chrome-for-testing-public/123.0.6312.122/win64/chrome-headless-shell-win64.zip" 605 | } 606 | ] 607 | } 608 | }, 609 | "124": { 610 | "milestone": "124", 611 | "version": "124.0.6367.207", 612 | "revision": "1274542", 613 | "downloads": { 614 | "chrome": [ 615 | { 616 | "platform": "linux64", 617 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/linux64/chrome-linux64.zip" 618 | }, 619 | { 620 | "platform": "mac-arm64", 621 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/mac-arm64/chrome-mac-arm64.zip" 622 | }, 623 | { 624 | "platform": "mac-x64", 625 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/mac-x64/chrome-mac-x64.zip" 626 | }, 627 | { 628 | "platform": "win32", 629 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/win32/chrome-win32.zip" 630 | }, 631 | { 632 | "platform": "win64", 633 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/win64/chrome-win64.zip" 634 | } 635 | ], 636 | "chromedriver": [ 637 | { 638 | "platform": "linux64", 639 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/linux64/chromedriver-linux64.zip" 640 | }, 641 | { 642 | "platform": "mac-arm64", 643 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/mac-arm64/chromedriver-mac-arm64.zip" 644 | }, 645 | { 646 | "platform": "mac-x64", 647 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/mac-x64/chromedriver-mac-x64.zip" 648 | }, 649 | { 650 | "platform": "win32", 651 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/win32/chromedriver-win32.zip" 652 | }, 653 | { 654 | "platform": "win64", 655 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/win64/chromedriver-win64.zip" 656 | } 657 | ], 658 | "chrome-headless-shell": [ 659 | { 660 | "platform": "linux64", 661 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/linux64/chrome-headless-shell-linux64.zip" 662 | }, 663 | { 664 | "platform": "mac-arm64", 665 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/mac-arm64/chrome-headless-shell-mac-arm64.zip" 666 | }, 667 | { 668 | "platform": "mac-x64", 669 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/mac-x64/chrome-headless-shell-mac-x64.zip" 670 | }, 671 | { 672 | "platform": "win32", 673 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/win32/chrome-headless-shell-win32.zip" 674 | }, 675 | { 676 | "platform": "win64", 677 | "url": "https://storage.googleapis.com/chrome-for-testing-public/124.0.6367.207/win64/chrome-headless-shell-win64.zip" 678 | } 679 | ] 680 | } 681 | }, 682 | "125": { 683 | "milestone": "125", 684 | "version": "125.0.6422.141", 685 | "revision": "1287751", 686 | "downloads": { 687 | "chrome": [ 688 | { 689 | "platform": "linux64", 690 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/linux64/chrome-linux64.zip" 691 | }, 692 | { 693 | "platform": "mac-arm64", 694 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/mac-arm64/chrome-mac-arm64.zip" 695 | }, 696 | { 697 | "platform": "mac-x64", 698 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/mac-x64/chrome-mac-x64.zip" 699 | }, 700 | { 701 | "platform": "win32", 702 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/win32/chrome-win32.zip" 703 | }, 704 | { 705 | "platform": "win64", 706 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/win64/chrome-win64.zip" 707 | } 708 | ], 709 | "chromedriver": [ 710 | { 711 | "platform": "linux64", 712 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/linux64/chromedriver-linux64.zip" 713 | }, 714 | { 715 | "platform": "mac-arm64", 716 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/mac-arm64/chromedriver-mac-arm64.zip" 717 | }, 718 | { 719 | "platform": "mac-x64", 720 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/mac-x64/chromedriver-mac-x64.zip" 721 | }, 722 | { 723 | "platform": "win32", 724 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/win32/chromedriver-win32.zip" 725 | }, 726 | { 727 | "platform": "win64", 728 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/win64/chromedriver-win64.zip" 729 | } 730 | ], 731 | "chrome-headless-shell": [ 732 | { 733 | "platform": "linux64", 734 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/linux64/chrome-headless-shell-linux64.zip" 735 | }, 736 | { 737 | "platform": "mac-arm64", 738 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/mac-arm64/chrome-headless-shell-mac-arm64.zip" 739 | }, 740 | { 741 | "platform": "mac-x64", 742 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/mac-x64/chrome-headless-shell-mac-x64.zip" 743 | }, 744 | { 745 | "platform": "win32", 746 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/win32/chrome-headless-shell-win32.zip" 747 | }, 748 | { 749 | "platform": "win64", 750 | "url": "https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.141/win64/chrome-headless-shell-win64.zip" 751 | } 752 | ] 753 | } 754 | }, 755 | "126": { 756 | "milestone": "126", 757 | "version": "126.0.6478.182", 758 | "revision": "1300313", 759 | "downloads": { 760 | "chrome": [ 761 | { 762 | "platform": "linux64", 763 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/linux64/chrome-linux64.zip" 764 | }, 765 | { 766 | "platform": "mac-arm64", 767 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/mac-arm64/chrome-mac-arm64.zip" 768 | }, 769 | { 770 | "platform": "mac-x64", 771 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/mac-x64/chrome-mac-x64.zip" 772 | }, 773 | { 774 | "platform": "win32", 775 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/win32/chrome-win32.zip" 776 | }, 777 | { 778 | "platform": "win64", 779 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/win64/chrome-win64.zip" 780 | } 781 | ], 782 | "chromedriver": [ 783 | { 784 | "platform": "linux64", 785 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/linux64/chromedriver-linux64.zip" 786 | }, 787 | { 788 | "platform": "mac-arm64", 789 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/mac-arm64/chromedriver-mac-arm64.zip" 790 | }, 791 | { 792 | "platform": "mac-x64", 793 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/mac-x64/chromedriver-mac-x64.zip" 794 | }, 795 | { 796 | "platform": "win32", 797 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/win32/chromedriver-win32.zip" 798 | }, 799 | { 800 | "platform": "win64", 801 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/win64/chromedriver-win64.zip" 802 | } 803 | ], 804 | "chrome-headless-shell": [ 805 | { 806 | "platform": "linux64", 807 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/linux64/chrome-headless-shell-linux64.zip" 808 | }, 809 | { 810 | "platform": "mac-arm64", 811 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/mac-arm64/chrome-headless-shell-mac-arm64.zip" 812 | }, 813 | { 814 | "platform": "mac-x64", 815 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/mac-x64/chrome-headless-shell-mac-x64.zip" 816 | }, 817 | { 818 | "platform": "win32", 819 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/win32/chrome-headless-shell-win32.zip" 820 | }, 821 | { 822 | "platform": "win64", 823 | "url": "https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.182/win64/chrome-headless-shell-win64.zip" 824 | } 825 | ] 826 | } 827 | }, 828 | "127": { 829 | "milestone": "127", 830 | "version": "127.0.6533.119", 831 | "revision": "1313161", 832 | "downloads": { 833 | "chrome": [ 834 | { 835 | "platform": "linux64", 836 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/linux64/chrome-linux64.zip" 837 | }, 838 | { 839 | "platform": "mac-arm64", 840 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/mac-arm64/chrome-mac-arm64.zip" 841 | }, 842 | { 843 | "platform": "mac-x64", 844 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/mac-x64/chrome-mac-x64.zip" 845 | }, 846 | { 847 | "platform": "win32", 848 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win32/chrome-win32.zip" 849 | }, 850 | { 851 | "platform": "win64", 852 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win64/chrome-win64.zip" 853 | } 854 | ], 855 | "chromedriver": [ 856 | { 857 | "platform": "linux64", 858 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/linux64/chromedriver-linux64.zip" 859 | }, 860 | { 861 | "platform": "mac-arm64", 862 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/mac-arm64/chromedriver-mac-arm64.zip" 863 | }, 864 | { 865 | "platform": "mac-x64", 866 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/mac-x64/chromedriver-mac-x64.zip" 867 | }, 868 | { 869 | "platform": "win32", 870 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win32/chromedriver-win32.zip" 871 | }, 872 | { 873 | "platform": "win64", 874 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win64/chromedriver-win64.zip" 875 | } 876 | ], 877 | "chrome-headless-shell": [ 878 | { 879 | "platform": "linux64", 880 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/linux64/chrome-headless-shell-linux64.zip" 881 | }, 882 | { 883 | "platform": "mac-arm64", 884 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/mac-arm64/chrome-headless-shell-mac-arm64.zip" 885 | }, 886 | { 887 | "platform": "mac-x64", 888 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/mac-x64/chrome-headless-shell-mac-x64.zip" 889 | }, 890 | { 891 | "platform": "win32", 892 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win32/chrome-headless-shell-win32.zip" 893 | }, 894 | { 895 | "platform": "win64", 896 | "url": "https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.119/win64/chrome-headless-shell-win64.zip" 897 | } 898 | ] 899 | } 900 | }, 901 | "128": { 902 | "milestone": "128", 903 | "version": "128.0.6613.137", 904 | "revision": "1331488", 905 | "downloads": { 906 | "chrome": [ 907 | { 908 | "platform": "linux64", 909 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chrome-linux64.zip" 910 | }, 911 | { 912 | "platform": "mac-arm64", 913 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/mac-arm64/chrome-mac-arm64.zip" 914 | }, 915 | { 916 | "platform": "mac-x64", 917 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/mac-x64/chrome-mac-x64.zip" 918 | }, 919 | { 920 | "platform": "win32", 921 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win32/chrome-win32.zip" 922 | }, 923 | { 924 | "platform": "win64", 925 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win64/chrome-win64.zip" 926 | } 927 | ], 928 | "chromedriver": [ 929 | { 930 | "platform": "linux64", 931 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chromedriver-linux64.zip" 932 | }, 933 | { 934 | "platform": "mac-arm64", 935 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/mac-arm64/chromedriver-mac-arm64.zip" 936 | }, 937 | { 938 | "platform": "mac-x64", 939 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/mac-x64/chromedriver-mac-x64.zip" 940 | }, 941 | { 942 | "platform": "win32", 943 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win32/chromedriver-win32.zip" 944 | }, 945 | { 946 | "platform": "win64", 947 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win64/chromedriver-win64.zip" 948 | } 949 | ], 950 | "chrome-headless-shell": [ 951 | { 952 | "platform": "linux64", 953 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chrome-headless-shell-linux64.zip" 954 | }, 955 | { 956 | "platform": "mac-arm64", 957 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/mac-arm64/chrome-headless-shell-mac-arm64.zip" 958 | }, 959 | { 960 | "platform": "mac-x64", 961 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/mac-x64/chrome-headless-shell-mac-x64.zip" 962 | }, 963 | { 964 | "platform": "win32", 965 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win32/chrome-headless-shell-win32.zip" 966 | }, 967 | { 968 | "platform": "win64", 969 | "url": "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/win64/chrome-headless-shell-win64.zip" 970 | } 971 | ] 972 | } 973 | }, 974 | "129": { 975 | "milestone": "129", 976 | "version": "129.0.6668.100", 977 | "revision": "1343869", 978 | "downloads": { 979 | "chrome": [ 980 | { 981 | "platform": "linux64", 982 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/linux64/chrome-linux64.zip" 983 | }, 984 | { 985 | "platform": "mac-arm64", 986 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/mac-arm64/chrome-mac-arm64.zip" 987 | }, 988 | { 989 | "platform": "mac-x64", 990 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/mac-x64/chrome-mac-x64.zip" 991 | }, 992 | { 993 | "platform": "win32", 994 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/win32/chrome-win32.zip" 995 | }, 996 | { 997 | "platform": "win64", 998 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/win64/chrome-win64.zip" 999 | } 1000 | ], 1001 | "chromedriver": [ 1002 | { 1003 | "platform": "linux64", 1004 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/linux64/chromedriver-linux64.zip" 1005 | }, 1006 | { 1007 | "platform": "mac-arm64", 1008 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/mac-arm64/chromedriver-mac-arm64.zip" 1009 | }, 1010 | { 1011 | "platform": "mac-x64", 1012 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/mac-x64/chromedriver-mac-x64.zip" 1013 | }, 1014 | { 1015 | "platform": "win32", 1016 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/win32/chromedriver-win32.zip" 1017 | }, 1018 | { 1019 | "platform": "win64", 1020 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/win64/chromedriver-win64.zip" 1021 | } 1022 | ], 1023 | "chrome-headless-shell": [ 1024 | { 1025 | "platform": "linux64", 1026 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/linux64/chrome-headless-shell-linux64.zip" 1027 | }, 1028 | { 1029 | "platform": "mac-arm64", 1030 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1031 | }, 1032 | { 1033 | "platform": "mac-x64", 1034 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/mac-x64/chrome-headless-shell-mac-x64.zip" 1035 | }, 1036 | { 1037 | "platform": "win32", 1038 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/win32/chrome-headless-shell-win32.zip" 1039 | }, 1040 | { 1041 | "platform": "win64", 1042 | "url": "https://storage.googleapis.com/chrome-for-testing-public/129.0.6668.100/win64/chrome-headless-shell-win64.zip" 1043 | } 1044 | ] 1045 | } 1046 | }, 1047 | "130": { 1048 | "milestone": "130", 1049 | "version": "130.0.6723.116", 1050 | "revision": "1356013", 1051 | "downloads": { 1052 | "chrome": [ 1053 | { 1054 | "platform": "linux64", 1055 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-linux64.zip" 1056 | }, 1057 | { 1058 | "platform": "mac-arm64", 1059 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/mac-arm64/chrome-mac-arm64.zip" 1060 | }, 1061 | { 1062 | "platform": "mac-x64", 1063 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/mac-x64/chrome-mac-x64.zip" 1064 | }, 1065 | { 1066 | "platform": "win32", 1067 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/win32/chrome-win32.zip" 1068 | }, 1069 | { 1070 | "platform": "win64", 1071 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/win64/chrome-win64.zip" 1072 | } 1073 | ], 1074 | "chromedriver": [ 1075 | { 1076 | "platform": "linux64", 1077 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chromedriver-linux64.zip" 1078 | }, 1079 | { 1080 | "platform": "mac-arm64", 1081 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/mac-arm64/chromedriver-mac-arm64.zip" 1082 | }, 1083 | { 1084 | "platform": "mac-x64", 1085 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/mac-x64/chromedriver-mac-x64.zip" 1086 | }, 1087 | { 1088 | "platform": "win32", 1089 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/win32/chromedriver-win32.zip" 1090 | }, 1091 | { 1092 | "platform": "win64", 1093 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/win64/chromedriver-win64.zip" 1094 | } 1095 | ], 1096 | "chrome-headless-shell": [ 1097 | { 1098 | "platform": "linux64", 1099 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/linux64/chrome-headless-shell-linux64.zip" 1100 | }, 1101 | { 1102 | "platform": "mac-arm64", 1103 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1104 | }, 1105 | { 1106 | "platform": "mac-x64", 1107 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/mac-x64/chrome-headless-shell-mac-x64.zip" 1108 | }, 1109 | { 1110 | "platform": "win32", 1111 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/win32/chrome-headless-shell-win32.zip" 1112 | }, 1113 | { 1114 | "platform": "win64", 1115 | "url": "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.116/win64/chrome-headless-shell-win64.zip" 1116 | } 1117 | ] 1118 | } 1119 | }, 1120 | "131": { 1121 | "milestone": "131", 1122 | "version": "131.0.6778.264", 1123 | "revision": "1368529", 1124 | "downloads": { 1125 | "chrome": [ 1126 | { 1127 | "platform": "linux64", 1128 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/linux64/chrome-linux64.zip" 1129 | }, 1130 | { 1131 | "platform": "mac-arm64", 1132 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/mac-arm64/chrome-mac-arm64.zip" 1133 | }, 1134 | { 1135 | "platform": "mac-x64", 1136 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/mac-x64/chrome-mac-x64.zip" 1137 | }, 1138 | { 1139 | "platform": "win32", 1140 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/win32/chrome-win32.zip" 1141 | }, 1142 | { 1143 | "platform": "win64", 1144 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/win64/chrome-win64.zip" 1145 | } 1146 | ], 1147 | "chromedriver": [ 1148 | { 1149 | "platform": "linux64", 1150 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/linux64/chromedriver-linux64.zip" 1151 | }, 1152 | { 1153 | "platform": "mac-arm64", 1154 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/mac-arm64/chromedriver-mac-arm64.zip" 1155 | }, 1156 | { 1157 | "platform": "mac-x64", 1158 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/mac-x64/chromedriver-mac-x64.zip" 1159 | }, 1160 | { 1161 | "platform": "win32", 1162 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/win32/chromedriver-win32.zip" 1163 | }, 1164 | { 1165 | "platform": "win64", 1166 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/win64/chromedriver-win64.zip" 1167 | } 1168 | ], 1169 | "chrome-headless-shell": [ 1170 | { 1171 | "platform": "linux64", 1172 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/linux64/chrome-headless-shell-linux64.zip" 1173 | }, 1174 | { 1175 | "platform": "mac-arm64", 1176 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1177 | }, 1178 | { 1179 | "platform": "mac-x64", 1180 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/mac-x64/chrome-headless-shell-mac-x64.zip" 1181 | }, 1182 | { 1183 | "platform": "win32", 1184 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/win32/chrome-headless-shell-win32.zip" 1185 | }, 1186 | { 1187 | "platform": "win64", 1188 | "url": "https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.264/win64/chrome-headless-shell-win64.zip" 1189 | } 1190 | ] 1191 | } 1192 | }, 1193 | "132": { 1194 | "milestone": "132", 1195 | "version": "132.0.6834.159", 1196 | "revision": "1381561", 1197 | "downloads": { 1198 | "chrome": [ 1199 | { 1200 | "platform": "linux64", 1201 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/linux64/chrome-linux64.zip" 1202 | }, 1203 | { 1204 | "platform": "mac-arm64", 1205 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/mac-arm64/chrome-mac-arm64.zip" 1206 | }, 1207 | { 1208 | "platform": "mac-x64", 1209 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/mac-x64/chrome-mac-x64.zip" 1210 | }, 1211 | { 1212 | "platform": "win32", 1213 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/win32/chrome-win32.zip" 1214 | }, 1215 | { 1216 | "platform": "win64", 1217 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/win64/chrome-win64.zip" 1218 | } 1219 | ], 1220 | "chromedriver": [ 1221 | { 1222 | "platform": "linux64", 1223 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/linux64/chromedriver-linux64.zip" 1224 | }, 1225 | { 1226 | "platform": "mac-arm64", 1227 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/mac-arm64/chromedriver-mac-arm64.zip" 1228 | }, 1229 | { 1230 | "platform": "mac-x64", 1231 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/mac-x64/chromedriver-mac-x64.zip" 1232 | }, 1233 | { 1234 | "platform": "win32", 1235 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/win32/chromedriver-win32.zip" 1236 | }, 1237 | { 1238 | "platform": "win64", 1239 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/win64/chromedriver-win64.zip" 1240 | } 1241 | ], 1242 | "chrome-headless-shell": [ 1243 | { 1244 | "platform": "linux64", 1245 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/linux64/chrome-headless-shell-linux64.zip" 1246 | }, 1247 | { 1248 | "platform": "mac-arm64", 1249 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1250 | }, 1251 | { 1252 | "platform": "mac-x64", 1253 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/mac-x64/chrome-headless-shell-mac-x64.zip" 1254 | }, 1255 | { 1256 | "platform": "win32", 1257 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/win32/chrome-headless-shell-win32.zip" 1258 | }, 1259 | { 1260 | "platform": "win64", 1261 | "url": "https://storage.googleapis.com/chrome-for-testing-public/132.0.6834.159/win64/chrome-headless-shell-win64.zip" 1262 | } 1263 | ] 1264 | } 1265 | }, 1266 | "133": { 1267 | "milestone": "133", 1268 | "version": "133.0.6943.141", 1269 | "revision": "1402768", 1270 | "downloads": { 1271 | "chrome": [ 1272 | { 1273 | "platform": "linux64", 1274 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/linux64/chrome-linux64.zip" 1275 | }, 1276 | { 1277 | "platform": "mac-arm64", 1278 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/mac-arm64/chrome-mac-arm64.zip" 1279 | }, 1280 | { 1281 | "platform": "mac-x64", 1282 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/mac-x64/chrome-mac-x64.zip" 1283 | }, 1284 | { 1285 | "platform": "win32", 1286 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/win32/chrome-win32.zip" 1287 | }, 1288 | { 1289 | "platform": "win64", 1290 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/win64/chrome-win64.zip" 1291 | } 1292 | ], 1293 | "chromedriver": [ 1294 | { 1295 | "platform": "linux64", 1296 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/linux64/chromedriver-linux64.zip" 1297 | }, 1298 | { 1299 | "platform": "mac-arm64", 1300 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/mac-arm64/chromedriver-mac-arm64.zip" 1301 | }, 1302 | { 1303 | "platform": "mac-x64", 1304 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/mac-x64/chromedriver-mac-x64.zip" 1305 | }, 1306 | { 1307 | "platform": "win32", 1308 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/win32/chromedriver-win32.zip" 1309 | }, 1310 | { 1311 | "platform": "win64", 1312 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/win64/chromedriver-win64.zip" 1313 | } 1314 | ], 1315 | "chrome-headless-shell": [ 1316 | { 1317 | "platform": "linux64", 1318 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/linux64/chrome-headless-shell-linux64.zip" 1319 | }, 1320 | { 1321 | "platform": "mac-arm64", 1322 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1323 | }, 1324 | { 1325 | "platform": "mac-x64", 1326 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/mac-x64/chrome-headless-shell-mac-x64.zip" 1327 | }, 1328 | { 1329 | "platform": "win32", 1330 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/win32/chrome-headless-shell-win32.zip" 1331 | }, 1332 | { 1333 | "platform": "win64", 1334 | "url": "https://storage.googleapis.com/chrome-for-testing-public/133.0.6943.141/win64/chrome-headless-shell-win64.zip" 1335 | } 1336 | ] 1337 | } 1338 | }, 1339 | "134": { 1340 | "milestone": "134", 1341 | "version": "134.0.6998.165", 1342 | "revision": "1415337", 1343 | "downloads": { 1344 | "chrome": [ 1345 | { 1346 | "platform": "linux64", 1347 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/linux64/chrome-linux64.zip" 1348 | }, 1349 | { 1350 | "platform": "mac-arm64", 1351 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/mac-arm64/chrome-mac-arm64.zip" 1352 | }, 1353 | { 1354 | "platform": "mac-x64", 1355 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/mac-x64/chrome-mac-x64.zip" 1356 | }, 1357 | { 1358 | "platform": "win32", 1359 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/win32/chrome-win32.zip" 1360 | }, 1361 | { 1362 | "platform": "win64", 1363 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/win64/chrome-win64.zip" 1364 | } 1365 | ], 1366 | "chromedriver": [ 1367 | { 1368 | "platform": "linux64", 1369 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/linux64/chromedriver-linux64.zip" 1370 | }, 1371 | { 1372 | "platform": "mac-arm64", 1373 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/mac-arm64/chromedriver-mac-arm64.zip" 1374 | }, 1375 | { 1376 | "platform": "mac-x64", 1377 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/mac-x64/chromedriver-mac-x64.zip" 1378 | }, 1379 | { 1380 | "platform": "win32", 1381 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/win32/chromedriver-win32.zip" 1382 | }, 1383 | { 1384 | "platform": "win64", 1385 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/win64/chromedriver-win64.zip" 1386 | } 1387 | ], 1388 | "chrome-headless-shell": [ 1389 | { 1390 | "platform": "linux64", 1391 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/linux64/chrome-headless-shell-linux64.zip" 1392 | }, 1393 | { 1394 | "platform": "mac-arm64", 1395 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1396 | }, 1397 | { 1398 | "platform": "mac-x64", 1399 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/mac-x64/chrome-headless-shell-mac-x64.zip" 1400 | }, 1401 | { 1402 | "platform": "win32", 1403 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/win32/chrome-headless-shell-win32.zip" 1404 | }, 1405 | { 1406 | "platform": "win64", 1407 | "url": "https://storage.googleapis.com/chrome-for-testing-public/134.0.6998.165/win64/chrome-headless-shell-win64.zip" 1408 | } 1409 | ] 1410 | } 1411 | }, 1412 | "135": { 1413 | "milestone": "135", 1414 | "version": "135.0.7049.114", 1415 | "revision": "1427262", 1416 | "downloads": { 1417 | "chrome": [ 1418 | { 1419 | "platform": "linux64", 1420 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/linux64/chrome-linux64.zip" 1421 | }, 1422 | { 1423 | "platform": "mac-arm64", 1424 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/mac-arm64/chrome-mac-arm64.zip" 1425 | }, 1426 | { 1427 | "platform": "mac-x64", 1428 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/mac-x64/chrome-mac-x64.zip" 1429 | }, 1430 | { 1431 | "platform": "win32", 1432 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/win32/chrome-win32.zip" 1433 | }, 1434 | { 1435 | "platform": "win64", 1436 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/win64/chrome-win64.zip" 1437 | } 1438 | ], 1439 | "chromedriver": [ 1440 | { 1441 | "platform": "linux64", 1442 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/linux64/chromedriver-linux64.zip" 1443 | }, 1444 | { 1445 | "platform": "mac-arm64", 1446 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/mac-arm64/chromedriver-mac-arm64.zip" 1447 | }, 1448 | { 1449 | "platform": "mac-x64", 1450 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/mac-x64/chromedriver-mac-x64.zip" 1451 | }, 1452 | { 1453 | "platform": "win32", 1454 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/win32/chromedriver-win32.zip" 1455 | }, 1456 | { 1457 | "platform": "win64", 1458 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/win64/chromedriver-win64.zip" 1459 | } 1460 | ], 1461 | "chrome-headless-shell": [ 1462 | { 1463 | "platform": "linux64", 1464 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/linux64/chrome-headless-shell-linux64.zip" 1465 | }, 1466 | { 1467 | "platform": "mac-arm64", 1468 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1469 | }, 1470 | { 1471 | "platform": "mac-x64", 1472 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/mac-x64/chrome-headless-shell-mac-x64.zip" 1473 | }, 1474 | { 1475 | "platform": "win32", 1476 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/win32/chrome-headless-shell-win32.zip" 1477 | }, 1478 | { 1479 | "platform": "win64", 1480 | "url": "https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.114/win64/chrome-headless-shell-win64.zip" 1481 | } 1482 | ] 1483 | } 1484 | }, 1485 | "136": { 1486 | "milestone": "136", 1487 | "version": "136.0.7103.113", 1488 | "revision": "1440670", 1489 | "downloads": { 1490 | "chrome": [ 1491 | { 1492 | "platform": "linux64", 1493 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/linux64/chrome-linux64.zip" 1494 | }, 1495 | { 1496 | "platform": "mac-arm64", 1497 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/mac-arm64/chrome-mac-arm64.zip" 1498 | }, 1499 | { 1500 | "platform": "mac-x64", 1501 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/mac-x64/chrome-mac-x64.zip" 1502 | }, 1503 | { 1504 | "platform": "win32", 1505 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/win32/chrome-win32.zip" 1506 | }, 1507 | { 1508 | "platform": "win64", 1509 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/win64/chrome-win64.zip" 1510 | } 1511 | ], 1512 | "chromedriver": [ 1513 | { 1514 | "platform": "linux64", 1515 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/linux64/chromedriver-linux64.zip" 1516 | }, 1517 | { 1518 | "platform": "mac-arm64", 1519 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/mac-arm64/chromedriver-mac-arm64.zip" 1520 | }, 1521 | { 1522 | "platform": "mac-x64", 1523 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/mac-x64/chromedriver-mac-x64.zip" 1524 | }, 1525 | { 1526 | "platform": "win32", 1527 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/win32/chromedriver-win32.zip" 1528 | }, 1529 | { 1530 | "platform": "win64", 1531 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/win64/chromedriver-win64.zip" 1532 | } 1533 | ], 1534 | "chrome-headless-shell": [ 1535 | { 1536 | "platform": "linux64", 1537 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/linux64/chrome-headless-shell-linux64.zip" 1538 | }, 1539 | { 1540 | "platform": "mac-arm64", 1541 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1542 | }, 1543 | { 1544 | "platform": "mac-x64", 1545 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/mac-x64/chrome-headless-shell-mac-x64.zip" 1546 | }, 1547 | { 1548 | "platform": "win32", 1549 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/win32/chrome-headless-shell-win32.zip" 1550 | }, 1551 | { 1552 | "platform": "win64", 1553 | "url": "https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.113/win64/chrome-headless-shell-win64.zip" 1554 | } 1555 | ] 1556 | } 1557 | }, 1558 | "137": { 1559 | "milestone": "137", 1560 | "version": "137.0.7151.68", 1561 | "revision": "1453031", 1562 | "downloads": { 1563 | "chrome": [ 1564 | { 1565 | "platform": "linux64", 1566 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/linux64/chrome-linux64.zip" 1567 | }, 1568 | { 1569 | "platform": "mac-arm64", 1570 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-arm64/chrome-mac-arm64.zip" 1571 | }, 1572 | { 1573 | "platform": "mac-x64", 1574 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-x64/chrome-mac-x64.zip" 1575 | }, 1576 | { 1577 | "platform": "win32", 1578 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win32/chrome-win32.zip" 1579 | }, 1580 | { 1581 | "platform": "win64", 1582 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win64/chrome-win64.zip" 1583 | } 1584 | ], 1585 | "chromedriver": [ 1586 | { 1587 | "platform": "linux64", 1588 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/linux64/chromedriver-linux64.zip" 1589 | }, 1590 | { 1591 | "platform": "mac-arm64", 1592 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-arm64/chromedriver-mac-arm64.zip" 1593 | }, 1594 | { 1595 | "platform": "mac-x64", 1596 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-x64/chromedriver-mac-x64.zip" 1597 | }, 1598 | { 1599 | "platform": "win32", 1600 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win32/chromedriver-win32.zip" 1601 | }, 1602 | { 1603 | "platform": "win64", 1604 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win64/chromedriver-win64.zip" 1605 | } 1606 | ], 1607 | "chrome-headless-shell": [ 1608 | { 1609 | "platform": "linux64", 1610 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/linux64/chrome-headless-shell-linux64.zip" 1611 | }, 1612 | { 1613 | "platform": "mac-arm64", 1614 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1615 | }, 1616 | { 1617 | "platform": "mac-x64", 1618 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/mac-x64/chrome-headless-shell-mac-x64.zip" 1619 | }, 1620 | { 1621 | "platform": "win32", 1622 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win32/chrome-headless-shell-win32.zip" 1623 | }, 1624 | { 1625 | "platform": "win64", 1626 | "url": "https://storage.googleapis.com/chrome-for-testing-public/137.0.7151.68/win64/chrome-headless-shell-win64.zip" 1627 | } 1628 | ] 1629 | } 1630 | }, 1631 | "138": { 1632 | "milestone": "138", 1633 | "version": "138.0.7204.15", 1634 | "revision": "1465706", 1635 | "downloads": { 1636 | "chrome": [ 1637 | { 1638 | "platform": "linux64", 1639 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/linux64/chrome-linux64.zip" 1640 | }, 1641 | { 1642 | "platform": "mac-arm64", 1643 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-arm64/chrome-mac-arm64.zip" 1644 | }, 1645 | { 1646 | "platform": "mac-x64", 1647 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-x64/chrome-mac-x64.zip" 1648 | }, 1649 | { 1650 | "platform": "win32", 1651 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win32/chrome-win32.zip" 1652 | }, 1653 | { 1654 | "platform": "win64", 1655 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win64/chrome-win64.zip" 1656 | } 1657 | ], 1658 | "chromedriver": [ 1659 | { 1660 | "platform": "linux64", 1661 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/linux64/chromedriver-linux64.zip" 1662 | }, 1663 | { 1664 | "platform": "mac-arm64", 1665 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-arm64/chromedriver-mac-arm64.zip" 1666 | }, 1667 | { 1668 | "platform": "mac-x64", 1669 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-x64/chromedriver-mac-x64.zip" 1670 | }, 1671 | { 1672 | "platform": "win32", 1673 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win32/chromedriver-win32.zip" 1674 | }, 1675 | { 1676 | "platform": "win64", 1677 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win64/chromedriver-win64.zip" 1678 | } 1679 | ], 1680 | "chrome-headless-shell": [ 1681 | { 1682 | "platform": "linux64", 1683 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/linux64/chrome-headless-shell-linux64.zip" 1684 | }, 1685 | { 1686 | "platform": "mac-arm64", 1687 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1688 | }, 1689 | { 1690 | "platform": "mac-x64", 1691 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/mac-x64/chrome-headless-shell-mac-x64.zip" 1692 | }, 1693 | { 1694 | "platform": "win32", 1695 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win32/chrome-headless-shell-win32.zip" 1696 | }, 1697 | { 1698 | "platform": "win64", 1699 | "url": "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.15/win64/chrome-headless-shell-win64.zip" 1700 | } 1701 | ] 1702 | } 1703 | }, 1704 | "139": { 1705 | "milestone": "139", 1706 | "version": "139.0.7226.0", 1707 | "revision": "1470985", 1708 | "downloads": { 1709 | "chrome": [ 1710 | { 1711 | "platform": "linux64", 1712 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/linux64/chrome-linux64.zip" 1713 | }, 1714 | { 1715 | "platform": "mac-arm64", 1716 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-arm64/chrome-mac-arm64.zip" 1717 | }, 1718 | { 1719 | "platform": "mac-x64", 1720 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-x64/chrome-mac-x64.zip" 1721 | }, 1722 | { 1723 | "platform": "win32", 1724 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win32/chrome-win32.zip" 1725 | }, 1726 | { 1727 | "platform": "win64", 1728 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win64/chrome-win64.zip" 1729 | } 1730 | ], 1731 | "chromedriver": [ 1732 | { 1733 | "platform": "linux64", 1734 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/linux64/chromedriver-linux64.zip" 1735 | }, 1736 | { 1737 | "platform": "mac-arm64", 1738 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-arm64/chromedriver-mac-arm64.zip" 1739 | }, 1740 | { 1741 | "platform": "mac-x64", 1742 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-x64/chromedriver-mac-x64.zip" 1743 | }, 1744 | { 1745 | "platform": "win32", 1746 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win32/chromedriver-win32.zip" 1747 | }, 1748 | { 1749 | "platform": "win64", 1750 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win64/chromedriver-win64.zip" 1751 | } 1752 | ], 1753 | "chrome-headless-shell": [ 1754 | { 1755 | "platform": "linux64", 1756 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/linux64/chrome-headless-shell-linux64.zip" 1757 | }, 1758 | { 1759 | "platform": "mac-arm64", 1760 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" 1761 | }, 1762 | { 1763 | "platform": "mac-x64", 1764 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/mac-x64/chrome-headless-shell-mac-x64.zip" 1765 | }, 1766 | { 1767 | "platform": "win32", 1768 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win32/chrome-headless-shell-win32.zip" 1769 | }, 1770 | { 1771 | "platform": "win64", 1772 | "url": "https://storage.googleapis.com/chrome-for-testing-public/139.0.7226.0/win64/chrome-headless-shell-win64.zip" 1773 | } 1774 | ] 1775 | } 1776 | } 1777 | } 1778 | } 1779 | -------------------------------------------------------------------------------- /data/latest-versions-per-milestone.json: -------------------------------------------------------------------------------- 1 | { 2 | "timestamp": "2025-06-08T12:12:37.857Z", 3 | "milestones": { 4 | "113": { 5 | "milestone": "113", 6 | "version": "113.0.5672.63", 7 | "revision": "1121455" 8 | }, 9 | "114": { 10 | "milestone": "114", 11 | "version": "114.0.5735.133", 12 | "revision": "1135570" 13 | }, 14 | "115": { 15 | "milestone": "115", 16 | "version": "115.0.5790.170", 17 | "revision": "1148114" 18 | }, 19 | "116": { 20 | "milestone": "116", 21 | "version": "116.0.5845.96", 22 | "revision": "1160321" 23 | }, 24 | "117": { 25 | "milestone": "117", 26 | "version": "117.0.5938.149", 27 | "revision": "1181205" 28 | }, 29 | "118": { 30 | "milestone": "118", 31 | "version": "118.0.5993.70", 32 | "revision": "1192594" 33 | }, 34 | "119": { 35 | "milestone": "119", 36 | "version": "119.0.6045.105", 37 | "revision": "1204232" 38 | }, 39 | "120": { 40 | "milestone": "120", 41 | "version": "120.0.6099.109", 42 | "revision": "1217362" 43 | }, 44 | "121": { 45 | "milestone": "121", 46 | "version": "121.0.6167.184", 47 | "revision": "1233107" 48 | }, 49 | "122": { 50 | "milestone": "122", 51 | "version": "122.0.6261.128", 52 | "revision": "1250580" 53 | }, 54 | "123": { 55 | "milestone": "123", 56 | "version": "123.0.6312.122", 57 | "revision": "1262506" 58 | }, 59 | "124": { 60 | "milestone": "124", 61 | "version": "124.0.6367.207", 62 | "revision": "1274542" 63 | }, 64 | "125": { 65 | "milestone": "125", 66 | "version": "125.0.6422.141", 67 | "revision": "1287751" 68 | }, 69 | "126": { 70 | "milestone": "126", 71 | "version": "126.0.6478.182", 72 | "revision": "1300313" 73 | }, 74 | "127": { 75 | "milestone": "127", 76 | "version": "127.0.6533.119", 77 | "revision": "1313161" 78 | }, 79 | "128": { 80 | "milestone": "128", 81 | "version": "128.0.6613.137", 82 | "revision": "1331488" 83 | }, 84 | "129": { 85 | "milestone": "129", 86 | "version": "129.0.6668.100", 87 | "revision": "1343869" 88 | }, 89 | "130": { 90 | "milestone": "130", 91 | "version": "130.0.6723.116", 92 | "revision": "1356013" 93 | }, 94 | "131": { 95 | "milestone": "131", 96 | "version": "131.0.6778.264", 97 | "revision": "1368529" 98 | }, 99 | "132": { 100 | "milestone": "132", 101 | "version": "132.0.6834.159", 102 | "revision": "1381561" 103 | }, 104 | "133": { 105 | "milestone": "133", 106 | "version": "133.0.6943.141", 107 | "revision": "1402768" 108 | }, 109 | "134": { 110 | "milestone": "134", 111 | "version": "134.0.6998.165", 112 | "revision": "1415337" 113 | }, 114 | "135": { 115 | "milestone": "135", 116 | "version": "135.0.7049.114", 117 | "revision": "1427262" 118 | }, 119 | "136": { 120 | "milestone": "136", 121 | "version": "136.0.7103.113", 122 | "revision": "1440670" 123 | }, 124 | "137": { 125 | "milestone": "137", 126 | "version": "137.0.7151.68", 127 | "revision": "1453031" 128 | }, 129 | "138": { 130 | "milestone": "138", 131 | "version": "138.0.7204.15", 132 | "revision": "1465706" 133 | }, 134 | "139": { 135 | "milestone": "139", 136 | "version": "139.0.7226.0", 137 | "revision": "1470985" 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /dist/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleChromeLabs/chrome-for-testing/d3d8f1e9e68de22d6a826f6d88abe504b0bac40c/dist/.nojekyll -------------------------------------------------------------------------------- /find-version.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This script gets Chrome release version numbers per platform 18 | // from the Chromium Dash API, figures out the most appropriate version 19 | // number to use for bundling with Puppeteer, and prints its download 20 | // URLs + their HTTP status codes. 21 | 22 | import fs from 'node:fs/promises'; 23 | 24 | import {binaries, checkDownloadsForVersion} from './url-utils.mjs'; 25 | import {isOlderVersion} from './is-older-version.mjs'; 26 | 27 | const findVersionForChannel = async (channel = 'Stable') => { 28 | const result = { 29 | channel, 30 | version: '0.0.0.0', 31 | revision: '0', 32 | ok: false, 33 | downloads: {}, 34 | }; 35 | for (const binary of binaries) { 36 | result.downloads[binary] = []; 37 | } 38 | console.log(`Checking the ${channel} channel…`); 39 | const apiEndpoint = `https://chromiumdash.appspot.com/fetch_releases?channel=${channel}&num=1&platform=Win32,Windows,Mac,Linux`; 40 | const response = await fetch(apiEndpoint); 41 | const data = await response.json(); 42 | 43 | let minVersion = `99999.99999.99999.99999`; 44 | const versions = new Set(); 45 | let minRevision = 9999999999999999; 46 | for (const entry of data) { 47 | const version = entry.version; 48 | const revision = String(entry.chromium_main_branch_position); 49 | versions.add(version); 50 | if (isOlderVersion(version, minVersion)) { 51 | minVersion = version; 52 | minRevision = revision; 53 | } 54 | } 55 | 56 | console.log(`Found versions:`, versions); 57 | console.log(`Recommended version for ${channel} channel:`, minVersion); 58 | result.version = minVersion; 59 | result.revision = minRevision; 60 | 61 | const version = minVersion; 62 | 63 | const checked = await checkDownloadsForVersion(version); 64 | 65 | for (const {binary, platform, url, status} of checked.downloads) { 66 | result.downloads[binary].push({ platform, url, status }); 67 | console.log(url, status); 68 | } 69 | console.log(checked.isOk ? '\u2705 OK' : '\u274C NOT OK'); 70 | result.ok = checked.isOk; 71 | 72 | return result; 73 | }; 74 | 75 | const allResults = { 76 | timestamp: new Date().toISOString(), 77 | ok: false, 78 | channels: {}, 79 | }; 80 | const channels = ['Stable', 'Beta', 'Dev', 'Canary']; 81 | let hasFailure = false; 82 | for (const channel of channels) { 83 | const result = await findVersionForChannel(channel); 84 | if (!result.ok) hasFailure = true; 85 | allResults.channels[channel] = result; 86 | console.log(''); 87 | } 88 | allResults.ok = !hasFailure; 89 | 90 | const json = JSON.stringify(allResults, null, '\t'); 91 | await fs.writeFile('./data/dashboard.json', `${json}\n`); 92 | -------------------------------------------------------------------------------- /generate-directory-index.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import fs from 'node:fs/promises'; 18 | 19 | import {glob} from 'glob'; 20 | 21 | import {escapeHtml, minifyHtml} from './html-utils.mjs'; 22 | 23 | const files = await glob('./*', { 24 | cwd: './dist/', 25 | }); 26 | 27 | const results = { 28 | digit: [], 29 | json: [], 30 | capOnly: [], 31 | cap: [], 32 | other: [], 33 | }; 34 | for (const fileName of files) { 35 | if (/^\d/.test(fileName)) { 36 | results.digit.push(fileName); 37 | continue; 38 | } 39 | if (fileName.endsWith('.json')) { 40 | results.json.push(fileName); 41 | continue; 42 | } 43 | if (/^[A-Z_]+$/.test(fileName)) { 44 | results.capOnly.push(fileName); 45 | continue; 46 | } 47 | if (/^[A-Z]/.test(fileName)) { 48 | results.cap.push(fileName); 49 | continue; 50 | } 51 | results.other.push(fileName); 52 | } 53 | 54 | results.digit.sort(); 55 | results.json.sort(); 56 | results.capOnly.sort(); 57 | results.cap.sort(); 58 | results.other.sort(); 59 | 60 | const allFileNames = [ 61 | ...results.json, 62 | ...results.capOnly, 63 | ...results.cap, 64 | ...results.digit, 65 | ...results.other, 66 | ]; 67 | 68 | const html = ` 69 | 70 | 71 | 72 | Chrome for Testing dashboard + API directory listing 73 | 74 | 75 | 79 | 84 | `; 85 | const minified = await minifyHtml(html); 86 | await fs.writeFile('./dist/files.html', minified); 87 | -------------------------------------------------------------------------------- /generate-extra-json.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {binaries, platforms, makeDownloadUrl} from './url-utils.mjs'; 18 | import { 19 | isOlderVersion, 20 | predatesChromeDriverAvailability, 21 | predatesChromeHeadlessShellAvailability, 22 | } from './is-older-version.mjs'; 23 | import { 24 | readJsonFile, 25 | writeJsonFile, 26 | writeMinifiedJsonFile, 27 | } from './json-utils.mjs'; 28 | 29 | const createTimestamp = () => { 30 | return new Date().toISOString(); 31 | }; 32 | 33 | const prepareLastKnownGoodVersionsData = async (data) => { 34 | const lastKnownGoodVersions = await readJsonFile('./data/last-known-good-versions.json'); 35 | for (const channelData of Object.values(data.channels)) { 36 | if (!channelData.ok) continue; 37 | const channelName = channelData.channel; 38 | const knownData = lastKnownGoodVersions.channels[channelName]; 39 | if ( 40 | knownData.version === channelData.version && 41 | knownData.revision === channelData.revision 42 | ) { 43 | continue; 44 | } 45 | lastKnownGoodVersions.timestamp = createTimestamp(); 46 | knownData.version = channelData.version; 47 | knownData.revision = channelData.revision; 48 | } 49 | return lastKnownGoodVersions; 50 | }; 51 | 52 | const updateKnownGoodVersions = async (filePath, lastKnownGoodVersions) => { 53 | const knownGoodVersions = await readJsonFile(filePath); 54 | const set = new Set(); 55 | const versions = knownGoodVersions.versions; 56 | for (const entry of versions) { 57 | set.add(entry.version); 58 | } 59 | for (const entry of Object.values(lastKnownGoodVersions.channels)) { 60 | const {version, revision} = entry; 61 | if (set.has(version)) { 62 | continue; 63 | } 64 | set.add(version); 65 | versions.push({ 66 | version, 67 | revision, 68 | }); 69 | knownGoodVersions.timestamp = createTimestamp(); 70 | } 71 | knownGoodVersions.versions.sort((a, b) => { 72 | if (isOlderVersion(a.version, b.version)) return -1; 73 | if (a.version === b.version) return 0; // This cannot happen. 74 | return 1; 75 | }); 76 | await writeJsonFile(filePath, knownGoodVersions); 77 | return knownGoodVersions; 78 | }; 79 | 80 | const addDownloads = (data, key) => { 81 | const copy = structuredClone(data); 82 | for (const channelData of Object.values(copy[key])) { 83 | const downloads = channelData.downloads = {}; 84 | for (const binary of binaries) { 85 | const version = channelData.version; 86 | if (binary === 'chromedriver' && predatesChromeDriverAvailability(version)) { 87 | continue; 88 | } 89 | if (binary === 'chrome-headless-shell' && predatesChromeHeadlessShellAvailability(version)) { 90 | continue; 91 | } 92 | if (binary === 'mojojs') { 93 | // Exclude mojojs from the dashboard + API. 94 | continue; 95 | } 96 | const downloadsForThisBinary = downloads[binary] = []; 97 | // `mojojs.zip` is platform-agnostic. (This is dead code right now, 98 | // but it’s useful in case we ever decide to include mojojs in the 99 | // dashboard + API.) 100 | if (binary === 'mojojs') { 101 | const url = makeDownloadUrl({ 102 | version: version, 103 | binary: binary, 104 | }); 105 | downloadsForThisBinary.push({ 106 | url: url, 107 | }); 108 | continue; 109 | } 110 | for (const platform of platforms) { 111 | const url = makeDownloadUrl({ 112 | version: version, 113 | platform: platform, 114 | binary: binary, 115 | }); 116 | downloadsForThisBinary.push({ 117 | platform: platform, 118 | url: url, 119 | }); 120 | } 121 | } 122 | } 123 | return copy; 124 | }; 125 | 126 | const updateLatestVersionsPerMilestone = async (filePath, lastKnownGoodVersionsData) => { 127 | const latestVersionsPerMilestoneData = await readJsonFile(filePath); 128 | const milestones = latestVersionsPerMilestoneData.milestones; 129 | let needsUpdate = false; 130 | 131 | for (const channelData of Object.values(lastKnownGoodVersionsData.channels)) { 132 | const {version, revision} = channelData; 133 | const milestone = version.split('.')[0]; 134 | if (Object.hasOwn(milestones, milestone)) { 135 | const current = milestones[milestone]; 136 | if (isOlderVersion(current.version, version)) { 137 | needsUpdate = true; 138 | current.version = version; 139 | current.revision = revision; 140 | } 141 | } else { 142 | needsUpdate = true; 143 | milestones[milestone] = { 144 | milestone, 145 | version, 146 | revision, 147 | }; 148 | } 149 | } 150 | 151 | if (needsUpdate) { 152 | latestVersionsPerMilestoneData.timestamp = createTimestamp(); 153 | } 154 | 155 | await writeJsonFile(filePath, latestVersionsPerMilestoneData); 156 | return latestVersionsPerMilestoneData; 157 | }; 158 | 159 | const prepareLatestPatchVersionsPerBuild = (knownGoodVersions) => { 160 | const map = new Map(); // partialVersion → versionInfo 161 | const re = /(?.*)\.(?\d+)$/; 162 | for (const entry of knownGoodVersions.versions) { 163 | const version = entry.version; 164 | const match = re.exec(version); 165 | const {build, patch} = match.groups; 166 | if (map.has(build)) { 167 | const knownEntry = map.get(build); 168 | if (isOlderVersion(knownEntry.version, version)) { 169 | map.set(build, entry); 170 | } 171 | } else { 172 | map.set(build, entry); 173 | } 174 | } 175 | const result = { 176 | timestamp: knownGoodVersions.timestamp, 177 | builds: {}, 178 | }; 179 | const builds = result.builds; 180 | for (const [partialVersion, entry] of map) { 181 | builds[partialVersion] = entry; 182 | } 183 | return result; 184 | }; 185 | 186 | const DASHBOARD_DATA = await readJsonFile('./data/dashboard.json'); 187 | 188 | const lastKnownGoodVersionsData = await prepareLastKnownGoodVersionsData(DASHBOARD_DATA); 189 | await writeJsonFile( 190 | './data/last-known-good-versions.json', 191 | lastKnownGoodVersionsData 192 | ); 193 | 194 | await writeJsonFile( 195 | './data/last-known-good-versions-with-downloads.json', 196 | addDownloads(lastKnownGoodVersionsData, 'channels') 197 | ); 198 | 199 | const latestVersionsPerMilestone = await updateLatestVersionsPerMilestone('./data/latest-versions-per-milestone.json', lastKnownGoodVersionsData); 200 | 201 | await writeJsonFile( 202 | './data/latest-versions-per-milestone-with-downloads.json', 203 | addDownloads(latestVersionsPerMilestone, 'milestones') 204 | ); 205 | 206 | const knownGoodVersions = await updateKnownGoodVersions('./data/known-good-versions.json', lastKnownGoodVersionsData); 207 | 208 | await writeJsonFile( 209 | './data/known-good-versions-with-downloads.json', 210 | addDownloads(knownGoodVersions, 'versions') 211 | ); 212 | 213 | const latestPatchVersionsPerBuild = prepareLatestPatchVersionsPerBuild(knownGoodVersions); 214 | await writeJsonFile( 215 | './data/latest-patch-versions-per-build.json', 216 | latestPatchVersionsPerBuild 217 | ); 218 | 219 | await writeJsonFile( 220 | './data/latest-patch-versions-per-build-with-downloads.json', 221 | addDownloads(latestPatchVersionsPerBuild, 'builds') 222 | ); 223 | 224 | const writePerVersionFiles = async () => { 225 | await Promise.all(addDownloads(knownGoodVersions, 'versions').versions.map((release) => { 226 | const fileName = `./dist/${release.version}.json`; 227 | return writeMinifiedJsonFile(fileName, release); 228 | })); 229 | }; 230 | 231 | await writePerVersionFiles(); 232 | -------------------------------------------------------------------------------- /generate-html.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import fs from 'node:fs/promises'; 18 | 19 | import {predatesChromeDriverAvailability, predatesChromeHeadlessShellAvailability} from './is-older-version.mjs'; 20 | import {readJsonFile} from './json-utils.mjs'; 21 | import {escapeHtml, minifyHtml} from './html-utils.mjs'; 22 | 23 | const OK = '\u2705'; 24 | const NOT_OK = '\u274C'; 25 | 26 | const renderDownloads = (downloads, version, forceOk = false) => { 27 | const list = []; 28 | for (const [binary, downloadsPerBinary] of Object.entries(downloads)) { 29 | if (binary === 'chromedriver' && predatesChromeDriverAvailability(version)) { 30 | continue; 31 | } 32 | if (binary === 'chrome-headless-shell' && predatesChromeHeadlessShellAvailability(version)) { 33 | continue; 34 | } 35 | if (binary === 'mojojs') { 36 | // Exclude mojojs from the dashboard + API. 37 | continue; 38 | } 39 | for (const download of downloadsPerBinary) { 40 | list.push( 41 | `${escapeHtml( 44 | binary 45 | )}${escapeHtml( 46 | download.platform 47 | )}${escapeHtml( 48 | download.url 49 | )}${forceOk ? '200' : escapeHtml(download.status)}` 50 | ); 51 | } 52 | } 53 | return ` 54 |
55 | 56 | 57 | 58 | 63 | ${list.join('')} 64 |
Binary 59 | Platform 60 | URL 61 | HTTP status 62 |
65 |
66 | `; 67 | }; 68 | 69 | const render = (data) => { 70 | const summary = []; 71 | const main = []; 72 | for (const [channel, channelData] of Object.entries(data.channels)) { 73 | const { version, revision, downloads } = channelData; 74 | const isOk = channelData.ok; 75 | if (isOk) { 76 | summary.push(` 77 | 78 | ${escapeHtml(channel)} 79 | ${escapeHtml(version)} 80 | r${escapeHtml(revision)} 81 | ${ OK } 82 | `); 83 | } else { 84 | const fallbackData = lastKnownGoodVersions.channels[channel]; 85 | const fallbackVersion = fallbackData.version; 86 | const fallbackRevision = fallbackData.revision; 87 | summary.push(` 88 | 89 | ${escapeHtml(channel)} 90 | ${escapeHtml(fallbackVersion)} 91 | r${escapeHtml(fallbackRevision)} 92 | ${ OK } 93 | 94 | ${escapeHtml(channel)} (upcoming) 95 | ${escapeHtml(version)} 96 | r${escapeHtml(revision)} 97 | ${ NOT_OK } 98 | `); 99 | } 100 | main.push(` 101 |
104 | `); 105 | if (isOk) { 106 | main.push(` 107 |

${escapeHtml(channel)}

108 |

Version: ${escapeHtml(version)} (r${escapeHtml(revision)})

109 | ${renderDownloads(downloads, version)} 110 | `); 111 | } else { 112 | const fallbackChannelData = lastKnownGoodVersions.channels[channel]; 113 | const fallbackVersion = fallbackChannelData.version; 114 | const fallbackRevision = fallbackChannelData.revision; 115 | const fallbackDownloads = fallbackChannelData.downloads; 116 | main.push(` 117 |

${escapeHtml(channel)}

118 |

Version: ${escapeHtml(fallbackVersion)} (r${escapeHtml(fallbackRevision)})

119 | ${renderDownloads(fallbackDownloads, fallbackVersion, true)} 120 |

Upcoming version: ${escapeHtml(version)} (r${escapeHtml(revision)})

121 | ${renderDownloads(downloads, version)} 122 | `); 123 | } 124 | main.push(` 125 |
126 | `); 127 | } 128 | return ` 129 |
130 | 131 | 132 | 133 | 138 | ${summary.join('')} 139 |
Channel 134 | Version 135 | Revision 136 | Status 137 |
140 |
141 | 142 | ${main.join('')} 143 | `; 144 | }; 145 | 146 | const data = await readJsonFile('./data/dashboard.json'); 147 | const lastKnownGoodVersions = await readJsonFile('data/last-known-good-versions-with-downloads.json'); 148 | 149 | const htmlTemplate = await fs.readFile('./_tpl/template.html', 'utf8'); 150 | const html = htmlTemplate.toString() 151 | .replace('%%%DATA%%%', render(data)) 152 | .replace('%%%TIMESTAMP%%%', data.timestamp); 153 | const minifiedHtml = await minifyHtml(html); 154 | await fs.writeFile('./dist/index.html', minifiedHtml); 155 | -------------------------------------------------------------------------------- /generate-latest-release.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import fs from 'node:fs/promises'; 18 | 19 | import {readJsonFile} from './json-utils.mjs'; 20 | 21 | const prepareMajorFiles = async () => { 22 | const data = await readJsonFile('./data/latest-versions-per-milestone.json'); 23 | for (const [milestone, versionData] of Object.entries(data.milestones)) { 24 | const fileName = `./dist/LATEST_RELEASE_${milestone}`; 25 | const contents = versionData.version; 26 | await fs.writeFile(fileName, contents); 27 | } 28 | }; 29 | 30 | const prepareMajorMinorBuildFiles = async () => { 31 | const data = await readJsonFile('./data/latest-patch-versions-per-build.json'); 32 | for (const [build, versionData] of Object.entries(data.builds)) { 33 | const fileName = `./dist/LATEST_RELEASE_${build}`; 34 | const contents = versionData.version; 35 | await fs.writeFile(fileName, contents); 36 | } 37 | }; 38 | 39 | const prepareChannelFiles = async () => { 40 | const data = await readJsonFile('./data/last-known-good-versions.json'); 41 | for (const [channelName, channelData] of Object.entries(data.channels)) { 42 | const fileName = `./dist/LATEST_RELEASE_${channelName.toUpperCase()}`; 43 | const contents = channelData.version; 44 | await fs.writeFile(fileName, contents); 45 | } 46 | }; 47 | 48 | await prepareMajorFiles(); 49 | await prepareMajorMinorBuildFiles(); 50 | await prepareChannelFiles(); 51 | -------------------------------------------------------------------------------- /html-utils.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {minify} from 'html-minifier-terser'; 18 | import {escape} from 'lodash-es'; 19 | 20 | export const minifyHtml = async (html) => { 21 | const minified = await minify(html, { 22 | collapseBooleanAttributes: true, 23 | collapseInlineTagWhitespace: false, 24 | collapseWhitespace: true, 25 | conservativeCollapse: false, 26 | decodeEntities: true, 27 | html5: true, 28 | includeAutoGeneratedTags: false, 29 | minifyCSS: true, 30 | minifyJS: true, 31 | preserveLineBreaks: false, 32 | preventAttributesEscaping: true, 33 | removeAttributeQuotes: true, 34 | removeComments: true, 35 | removeEmptyAttributes: true, 36 | removeEmptyElements: false, 37 | removeOptionalTags: false, 38 | removeRedundantAttributes: true, 39 | removeTagWhitespace: false, 40 | sortAttributes: true, 41 | sortClassName: true, 42 | }); 43 | return minified; 44 | }; 45 | 46 | export const escapeHtml = escape; 47 | -------------------------------------------------------------------------------- /is-older-version.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // Why pull in `semver.lt()` when we could instead we can have some fun? 18 | 19 | const reVersionNumber = /^(?\d+)\.(?\d+)\.(?\d+).(?\d+)$/; 20 | 21 | const hash = (versionNumber) => { 22 | // XXXXX.XXXXX.XXXXX.XXXXX 23 | // 00000 00000 00000 24 | // 00000 00000 25 | // 00000 26 | const match = reVersionNumber.exec(versionNumber); 27 | const major = BigInt(match.groups.major); 28 | const minor = BigInt(match.groups.minor); 29 | const build = BigInt(match.groups.build); 30 | const patch = BigInt(match.groups.patch); 31 | const hashed = 32 | major * 1_00000_00000_00000n 33 | + minor * 1_00000_00000n 34 | + build * 1_00000n 35 | + patch; 36 | return hashed; 37 | }; 38 | 39 | export const isOlderVersion = (a, b) => { 40 | return hash(a) < hash(b); 41 | }; 42 | 43 | export const predatesChromeDriverAvailability = (version) => { 44 | // ChromeDriver is only available via CfT from M115 onwards. 45 | const firstChromeDriverVersion = '115.0.5763.0'; 46 | const predates = isOlderVersion(version, firstChromeDriverVersion); 47 | return predates; 48 | }; 49 | 50 | export const predatesChromeHeadlessShellAvailability = (version) => { 51 | // chrome-headless-shell is only available via CfT from M120 onwards. 52 | const firstChromeHeadlessShellVersion = '120.0.6098.0'; 53 | const predates = isOlderVersion(version, firstChromeHeadlessShellVersion); 54 | return predates; 55 | }; 56 | 57 | export const predatesMojoJsAvailability = (version) => { 58 | // mojojs is only available via CfT from M123 onwards. 59 | const firstMojoJsVersion = '123.0.6309.0'; 60 | const predates = isOlderVersion(version, firstMojoJsVersion); 61 | return predates; 62 | }; 63 | -------------------------------------------------------------------------------- /json-utils.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import fs from 'node:fs/promises'; 18 | 19 | export const readJsonFile = async (filePath) => { 20 | const json = await fs.readFile(filePath, 'utf8'); 21 | const data = JSON.parse(json); 22 | return data; 23 | }; 24 | 25 | export const writeJsonFile = async (filePath, data) => { 26 | const json = `${JSON.stringify(data, null, '\t')}\n`; 27 | await fs.writeFile(filePath, json); 28 | }; 29 | 30 | export const writeMinifiedJsonFile = async (filePath, data) => { 31 | const json = JSON.stringify(data); 32 | await fs.writeFile(filePath, json); 33 | }; 34 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chrome-for-testing", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "devDependencies": { 8 | "html-minifier-terser": "7.2.0", 9 | "jsesc": "3.0.2", 10 | "lodash-es": "4.17.21" 11 | } 12 | }, 13 | "node_modules/@jridgewell/gen-mapping": { 14 | "version": "0.3.3", 15 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 16 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 17 | "dev": true, 18 | "dependencies": { 19 | "@jridgewell/set-array": "^1.0.1", 20 | "@jridgewell/sourcemap-codec": "^1.4.10", 21 | "@jridgewell/trace-mapping": "^0.3.9" 22 | }, 23 | "engines": { 24 | "node": ">=6.0.0" 25 | } 26 | }, 27 | "node_modules/@jridgewell/resolve-uri": { 28 | "version": "3.1.0", 29 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", 30 | "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", 31 | "dev": true, 32 | "engines": { 33 | "node": ">=6.0.0" 34 | } 35 | }, 36 | "node_modules/@jridgewell/set-array": { 37 | "version": "1.1.2", 38 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 39 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 40 | "dev": true, 41 | "engines": { 42 | "node": ">=6.0.0" 43 | } 44 | }, 45 | "node_modules/@jridgewell/source-map": { 46 | "version": "0.3.3", 47 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", 48 | "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", 49 | "dev": true, 50 | "dependencies": { 51 | "@jridgewell/gen-mapping": "^0.3.0", 52 | "@jridgewell/trace-mapping": "^0.3.9" 53 | } 54 | }, 55 | "node_modules/@jridgewell/sourcemap-codec": { 56 | "version": "1.4.15", 57 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 58 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 59 | "dev": true 60 | }, 61 | "node_modules/@jridgewell/trace-mapping": { 62 | "version": "0.3.18", 63 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", 64 | "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", 65 | "dev": true, 66 | "dependencies": { 67 | "@jridgewell/resolve-uri": "3.1.0", 68 | "@jridgewell/sourcemap-codec": "1.4.14" 69 | } 70 | }, 71 | "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { 72 | "version": "1.4.14", 73 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", 74 | "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", 75 | "dev": true 76 | }, 77 | "node_modules/acorn": { 78 | "version": "8.8.2", 79 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", 80 | "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", 81 | "dev": true, 82 | "bin": { 83 | "acorn": "bin/acorn" 84 | }, 85 | "engines": { 86 | "node": ">=0.4.0" 87 | } 88 | }, 89 | "node_modules/buffer-from": { 90 | "version": "1.1.2", 91 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 92 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 93 | "dev": true 94 | }, 95 | "node_modules/camel-case": { 96 | "version": "4.1.2", 97 | "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", 98 | "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", 99 | "dev": true, 100 | "dependencies": { 101 | "pascal-case": "^3.1.2", 102 | "tslib": "^2.0.3" 103 | } 104 | }, 105 | "node_modules/clean-css": { 106 | "version": "5.3.2", 107 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", 108 | "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", 109 | "dev": true, 110 | "dependencies": { 111 | "source-map": "~0.6.0" 112 | }, 113 | "engines": { 114 | "node": ">= 10.0" 115 | } 116 | }, 117 | "node_modules/commander": { 118 | "version": "10.0.1", 119 | "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", 120 | "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", 121 | "dev": true, 122 | "engines": { 123 | "node": ">=14" 124 | } 125 | }, 126 | "node_modules/dot-case": { 127 | "version": "3.0.4", 128 | "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", 129 | "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", 130 | "dev": true, 131 | "dependencies": { 132 | "no-case": "^3.0.4", 133 | "tslib": "^2.0.3" 134 | } 135 | }, 136 | "node_modules/entities": { 137 | "version": "4.5.0", 138 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 139 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 140 | "dev": true, 141 | "engines": { 142 | "node": ">=0.12" 143 | }, 144 | "funding": { 145 | "url": "https://github.com/fb55/entities?sponsor=1" 146 | } 147 | }, 148 | "node_modules/html-minifier-terser": { 149 | "version": "7.2.0", 150 | "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", 151 | "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", 152 | "dev": true, 153 | "dependencies": { 154 | "camel-case": "^4.1.2", 155 | "clean-css": "~5.3.2", 156 | "commander": "^10.0.0", 157 | "entities": "^4.4.0", 158 | "param-case": "^3.0.4", 159 | "relateurl": "^0.2.7", 160 | "terser": "^5.15.1" 161 | }, 162 | "bin": { 163 | "html-minifier-terser": "cli.js" 164 | }, 165 | "engines": { 166 | "node": "^14.13.1 || >=16.0.0" 167 | } 168 | }, 169 | "node_modules/jsesc": { 170 | "version": "3.0.2", 171 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", 172 | "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", 173 | "dev": true, 174 | "bin": { 175 | "jsesc": "bin/jsesc" 176 | }, 177 | "engines": { 178 | "node": ">=6" 179 | } 180 | }, 181 | "node_modules/lodash-es": { 182 | "version": "4.17.21", 183 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", 184 | "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", 185 | "dev": true 186 | }, 187 | "node_modules/lower-case": { 188 | "version": "2.0.2", 189 | "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", 190 | "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", 191 | "dev": true, 192 | "dependencies": { 193 | "tslib": "^2.0.3" 194 | } 195 | }, 196 | "node_modules/no-case": { 197 | "version": "3.0.4", 198 | "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", 199 | "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", 200 | "dev": true, 201 | "dependencies": { 202 | "lower-case": "^2.0.2", 203 | "tslib": "^2.0.3" 204 | } 205 | }, 206 | "node_modules/param-case": { 207 | "version": "3.0.4", 208 | "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", 209 | "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", 210 | "dev": true, 211 | "dependencies": { 212 | "dot-case": "^3.0.4", 213 | "tslib": "^2.0.3" 214 | } 215 | }, 216 | "node_modules/pascal-case": { 217 | "version": "3.1.2", 218 | "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", 219 | "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", 220 | "dev": true, 221 | "dependencies": { 222 | "no-case": "^3.0.4", 223 | "tslib": "^2.0.3" 224 | } 225 | }, 226 | "node_modules/relateurl": { 227 | "version": "0.2.7", 228 | "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", 229 | "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", 230 | "dev": true, 231 | "engines": { 232 | "node": ">= 0.10" 233 | } 234 | }, 235 | "node_modules/source-map": { 236 | "version": "0.6.1", 237 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 238 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 239 | "dev": true, 240 | "engines": { 241 | "node": ">=0.10.0" 242 | } 243 | }, 244 | "node_modules/source-map-support": { 245 | "version": "0.5.21", 246 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 247 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 248 | "dev": true, 249 | "dependencies": { 250 | "buffer-from": "^1.0.0", 251 | "source-map": "^0.6.0" 252 | } 253 | }, 254 | "node_modules/terser": { 255 | "version": "5.17.7", 256 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", 257 | "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", 258 | "dev": true, 259 | "dependencies": { 260 | "@jridgewell/source-map": "^0.3.3", 261 | "acorn": "^8.8.2", 262 | "commander": "^2.20.0", 263 | "source-map-support": "~0.5.20" 264 | }, 265 | "bin": { 266 | "terser": "bin/terser" 267 | }, 268 | "engines": { 269 | "node": ">=10" 270 | } 271 | }, 272 | "node_modules/terser/node_modules/commander": { 273 | "version": "2.20.3", 274 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 275 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 276 | "dev": true 277 | }, 278 | "node_modules/tslib": { 279 | "version": "2.5.3", 280 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", 281 | "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", 282 | "dev": true 283 | } 284 | }, 285 | "dependencies": { 286 | "@jridgewell/gen-mapping": { 287 | "version": "0.3.3", 288 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 289 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 290 | "dev": true, 291 | "requires": { 292 | "@jridgewell/set-array": "^1.0.1", 293 | "@jridgewell/sourcemap-codec": "^1.4.10", 294 | "@jridgewell/trace-mapping": "^0.3.9" 295 | } 296 | }, 297 | "@jridgewell/resolve-uri": { 298 | "version": "3.1.0", 299 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", 300 | "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", 301 | "dev": true 302 | }, 303 | "@jridgewell/set-array": { 304 | "version": "1.1.2", 305 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 306 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 307 | "dev": true 308 | }, 309 | "@jridgewell/source-map": { 310 | "version": "0.3.3", 311 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", 312 | "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", 313 | "dev": true, 314 | "requires": { 315 | "@jridgewell/gen-mapping": "^0.3.0", 316 | "@jridgewell/trace-mapping": "^0.3.9" 317 | } 318 | }, 319 | "@jridgewell/sourcemap-codec": { 320 | "version": "1.4.15", 321 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 322 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 323 | "dev": true 324 | }, 325 | "@jridgewell/trace-mapping": { 326 | "version": "0.3.18", 327 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", 328 | "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", 329 | "dev": true, 330 | "requires": { 331 | "@jridgewell/resolve-uri": "3.1.0", 332 | "@jridgewell/sourcemap-codec": "1.4.14" 333 | }, 334 | "dependencies": { 335 | "@jridgewell/sourcemap-codec": { 336 | "version": "1.4.14", 337 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", 338 | "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", 339 | "dev": true 340 | } 341 | } 342 | }, 343 | "acorn": { 344 | "version": "8.8.2", 345 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", 346 | "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", 347 | "dev": true 348 | }, 349 | "buffer-from": { 350 | "version": "1.1.2", 351 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 352 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 353 | "dev": true 354 | }, 355 | "camel-case": { 356 | "version": "4.1.2", 357 | "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", 358 | "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", 359 | "dev": true, 360 | "requires": { 361 | "pascal-case": "^3.1.2", 362 | "tslib": "^2.0.3" 363 | } 364 | }, 365 | "clean-css": { 366 | "version": "5.3.2", 367 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", 368 | "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", 369 | "dev": true, 370 | "requires": { 371 | "source-map": "~0.6.0" 372 | } 373 | }, 374 | "commander": { 375 | "version": "10.0.1", 376 | "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", 377 | "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", 378 | "dev": true 379 | }, 380 | "dot-case": { 381 | "version": "3.0.4", 382 | "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", 383 | "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", 384 | "dev": true, 385 | "requires": { 386 | "no-case": "^3.0.4", 387 | "tslib": "^2.0.3" 388 | } 389 | }, 390 | "entities": { 391 | "version": "4.5.0", 392 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 393 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 394 | "dev": true 395 | }, 396 | "html-minifier-terser": { 397 | "version": "7.2.0", 398 | "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", 399 | "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", 400 | "dev": true, 401 | "requires": { 402 | "camel-case": "^4.1.2", 403 | "clean-css": "~5.3.2", 404 | "commander": "^10.0.0", 405 | "entities": "^4.4.0", 406 | "param-case": "^3.0.4", 407 | "relateurl": "^0.2.7", 408 | "terser": "^5.15.1" 409 | } 410 | }, 411 | "jsesc": { 412 | "version": "3.0.2", 413 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", 414 | "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", 415 | "dev": true 416 | }, 417 | "lodash-es": { 418 | "version": "4.17.21", 419 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", 420 | "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", 421 | "dev": true 422 | }, 423 | "lower-case": { 424 | "version": "2.0.2", 425 | "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", 426 | "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", 427 | "dev": true, 428 | "requires": { 429 | "tslib": "^2.0.3" 430 | } 431 | }, 432 | "no-case": { 433 | "version": "3.0.4", 434 | "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", 435 | "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", 436 | "dev": true, 437 | "requires": { 438 | "lower-case": "^2.0.2", 439 | "tslib": "^2.0.3" 440 | } 441 | }, 442 | "param-case": { 443 | "version": "3.0.4", 444 | "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", 445 | "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", 446 | "dev": true, 447 | "requires": { 448 | "dot-case": "^3.0.4", 449 | "tslib": "^2.0.3" 450 | } 451 | }, 452 | "pascal-case": { 453 | "version": "3.1.2", 454 | "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", 455 | "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", 456 | "dev": true, 457 | "requires": { 458 | "no-case": "^3.0.4", 459 | "tslib": "^2.0.3" 460 | } 461 | }, 462 | "relateurl": { 463 | "version": "0.2.7", 464 | "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", 465 | "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", 466 | "dev": true 467 | }, 468 | "source-map": { 469 | "version": "0.6.1", 470 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 471 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 472 | "dev": true 473 | }, 474 | "source-map-support": { 475 | "version": "0.5.21", 476 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 477 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 478 | "dev": true, 479 | "requires": { 480 | "buffer-from": "^1.0.0", 481 | "source-map": "^0.6.0" 482 | } 483 | }, 484 | "terser": { 485 | "version": "5.17.7", 486 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", 487 | "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", 488 | "dev": true, 489 | "requires": { 490 | "@jridgewell/source-map": "^0.3.3", 491 | "acorn": "^8.8.2", 492 | "commander": "^2.20.0", 493 | "source-map-support": "~0.5.20" 494 | }, 495 | "dependencies": { 496 | "commander": { 497 | "version": "2.20.3", 498 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 499 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 500 | "dev": true 501 | } 502 | } 503 | }, 504 | "tslib": { 505 | "version": "2.5.3", 506 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", 507 | "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", 508 | "dev": true 509 | } 510 | } 511 | } 512 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "repository": { 4 | "type": "git", 5 | "url": "https://github.com/GoogleChromeLabs/chrome-for-testing" 6 | }, 7 | "scripts": { 8 | "check": "node --no-warnings check-version.mjs", 9 | "find": "node --no-warnings find-version.mjs", 10 | "json": "node generate-extra-json.mjs && for id in known-good-versions known-good-versions-with-downloads last-known-good-versions last-known-good-versions-with-downloads latest-patch-versions-per-build latest-patch-versions-per-build-with-downloads latest-versions-per-milestone latest-versions-per-milestone-with-downloads; do jsesc --object --json < \"data/${id}.json\" > \"dist/${id}.json\"; done", 11 | "txt": "node generate-latest-release.mjs", 12 | "index": "node generate-directory-index.mjs", 13 | "render": "node generate-html.mjs && cp logo.svg dist/logo.svg && node generate-directory-index.mjs", 14 | "build": "npm run find && npm run json && npm run txt && npm run render" 15 | }, 16 | "devDependencies": { 17 | "glob": "^10.3.10", 18 | "html-minifier-terser": "7.2.0", 19 | "jsesc": "3.0.2", 20 | "lodash-es": "4.17.21" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /url-utils.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the “License”); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an “AS IS” BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import assert from 'node:assert'; 18 | 19 | import { 20 | predatesChromeDriverAvailability, 21 | predatesChromeHeadlessShellAvailability, 22 | predatesMojoJsAvailability, 23 | } from './is-older-version.mjs'; 24 | 25 | // Lorry download bucket labels. 26 | export const platforms = new Set([ 27 | 'linux64', 28 | 'mac-arm64', 29 | 'mac-x64', 30 | 'win32', 31 | 'win64', 32 | ]); 33 | 34 | export const binaries = new Set([ 35 | 'chrome', 36 | 'chromedriver', 37 | 'chrome-headless-shell', 38 | 'mojojs', 39 | ]); 40 | 41 | export const makeDownloadUrl = ({ version, platform, binary = 'chrome' }) => { 42 | assert(binaries.has(binary)); 43 | if (binary === 'mojojs') { 44 | return `https://storage.googleapis.com/chrome-for-testing-public/${version}/${binary}.zip`; 45 | } 46 | assert(platforms.has(platform)); 47 | const url = `https://storage.googleapis.com/chrome-for-testing-public/${version}/${platform}/${binary}-${platform}.zip`; 48 | return url; 49 | }; 50 | 51 | export const makeDownloadsForVersion = (version) => { 52 | const urls = []; 53 | for (const binary of binaries) { 54 | // `mojojs.zip` is platform-agnostic. 55 | if (binary === 'mojojs') { 56 | const url = makeDownloadUrl({ version, binary }); 57 | urls.push({ binary, url }); 58 | continue; 59 | } 60 | // Other CfT assets are platform-specific. 61 | for (const platform of platforms) { 62 | const url = makeDownloadUrl({ version, platform, binary }); 63 | urls.push({ binary, platform, url }); 64 | } 65 | } 66 | return urls; 67 | }; 68 | 69 | export const checkDownloadsForVersion = async (version) => { 70 | const downloads = makeDownloadsForVersion(version); 71 | 72 | // Add `isOk` and `status` properties. 73 | let hasFailure = false; 74 | for (const download of downloads) { 75 | const {binary, url} = download; 76 | const response = await fetch(url, { method: 'head' }); 77 | const status = response.status; 78 | if (status !== 200) { 79 | const ignoreChromeDriver = binary === 'chromedriver' && predatesChromeDriverAvailability(version); 80 | const ignoreChromeHeadlessShell = binary === 'chrome-headless-shell' && predatesChromeHeadlessShellAvailability(version); 81 | const ignoreMojoJs = binary === 'mojojs' && predatesMojoJsAvailability(version); 82 | const ignore = ignoreChromeDriver || ignoreChromeHeadlessShell || ignoreMojoJs; 83 | if (ignore) { 84 | // Do not consider missing ChromeDriver, chrome-headless-shell, 85 | // or MojoJS assets a failure for versions predating their CfT 86 | // release. 87 | } else { 88 | download.isOk = false; 89 | hasFailure = true; 90 | } 91 | } else { 92 | download.isOk = true; 93 | } 94 | download.status = status; 95 | } 96 | return { 97 | downloads, 98 | isOk: !hasFailure, 99 | }; 100 | }; 101 | --------------------------------------------------------------------------------