minigame
This commit is contained in:
201
node_modules/chromedriver/LICENSE.txt
generated
vendored
Normal file
201
node_modules/chromedriver/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2014 Giovanni Bassi and Elemar Jr.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
327
node_modules/chromedriver/README.md
generated
vendored
Normal file
327
node_modules/chromedriver/README.md
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
# ChromeDriver
|
||||
|
||||
[](https://github.com/giggio/node-chromedriver/actions/workflows/build.yml)
|
||||
[](https://www.npmjs.com/package/chromedriver)
|
||||
|
||||
An NPM wrapper for Selenium [ChromeDriver](https://sites.google.com/chromium.org/driver/).
|
||||
|
||||
## Building and Installing
|
||||
|
||||
```shell
|
||||
npm install chromedriver
|
||||
```
|
||||
|
||||
Or grab the source and
|
||||
|
||||
```shell
|
||||
node ./install.js
|
||||
```
|
||||
|
||||
What this is really doing is just grabbing a particular "blessed" (by
|
||||
this module) version of ChromeDriver. As new versions are released
|
||||
and vetted, this module will be updated accordingly.
|
||||
|
||||
The package has been set up to fetch and run ChromeDriver for MacOS (darwin),
|
||||
Linux based platforms (as identified by Node.js), and Windows. If you
|
||||
spot any platform weirdness, let us know or send a patch.
|
||||
|
||||
## Force download
|
||||
|
||||
By default this package, when installed, will search for an existing
|
||||
Chromedriver binary in your configured temp directory. If found, and it is the
|
||||
correct version, it will simply copy it to your node_modules directory. You can
|
||||
force it always download by configuring it:
|
||||
|
||||
```shell
|
||||
npm install chromedriver --chromedriver-force-download
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
chromedriver_force_download=true
|
||||
```
|
||||
|
||||
Another option is to use PATH variable `CHROMEDRIVER_FORCE_DOWNLOAD`.
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_FORCE_DOWNLOAD=true npm install chromedriver
|
||||
```
|
||||
|
||||
## Custom binaries url
|
||||
|
||||
To use a mirror of the ChromeDriver binaries use npm config property `chromedriver_cdnurl`.
|
||||
Default is `https://chromedriver.storage.googleapis.com`.
|
||||
|
||||
```shell
|
||||
npm install chromedriver --chromedriver_cdnurl=https://npmmirror.com/mirrors/chromedriver
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
chromedriver_cdnurl=https://npmmirror.com/mirrors/chromedriver
|
||||
```
|
||||
|
||||
Another option is to use PATH variable `CHROMEDRIVER_CDNURL`.
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_CDNURL=https://npmmirror.com/mirrors/chromedriver npm install chromedriver
|
||||
```
|
||||
|
||||
## Custom binaries file
|
||||
|
||||
To get the chromedriver from the filesystem instead of a web request use the npm config property `chromedriver_filepath`.
|
||||
|
||||
```shell
|
||||
npm install chromedriver --chromedriver_filepath=/path/to/chromedriver_mac64.zip
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
chromedriver_filepath=/path/to/chromedriver_mac64.zip
|
||||
```
|
||||
|
||||
Another option is to use the PATH variable `CHROMEDRIVER_FILEPATH`
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_FILEPATH=/path/to/chromedriver_mac64.zip
|
||||
```
|
||||
|
||||
This variable can be used to set either a `.zip` file or the binary itself, eg:
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_FILEPATH=/bin/chromedriver
|
||||
```
|
||||
|
||||
## Custom download options
|
||||
|
||||
Install through a proxy.
|
||||
|
||||
```shell
|
||||
npm config set proxy http://[user:pwd]@domain.tld:port
|
||||
npm config set https-proxy http://[user:pwd]@domain.tld:port
|
||||
```
|
||||
|
||||
Use different User-Agent.
|
||||
|
||||
```shell
|
||||
npm config set user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"
|
||||
```
|
||||
|
||||
## Skipping chromedriver download
|
||||
|
||||
You may wish to skip the downloading of the chromedriver binary file, for example if you know for certain that it is already there or if you want to use a system binary and just use this module as an interface to interact with it.
|
||||
|
||||
To achieve this you can use the npm config property `chromedriver_skip_download`.
|
||||
|
||||
```shell
|
||||
npm install chromedriver --chromedriver_skip_download=true
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
chromedriver_skip_download=true
|
||||
```
|
||||
|
||||
Another option is to use the PATH variable `CHROMEDRIVER_SKIP_DOWNLOAD`
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_SKIP_DOWNLOAD=true
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
```shell
|
||||
bin/chromedriver [arguments]
|
||||
```
|
||||
|
||||
And npm will install a link to the binary in `node_modules/.bin` as
|
||||
it is wont to do.
|
||||
|
||||
## Running with Selenium WebDriver
|
||||
|
||||
```javascript
|
||||
require('chromedriver');
|
||||
var webdriver = require('selenium-webdriver');
|
||||
var driver = new webdriver.Builder()
|
||||
.forBrowser('chrome')
|
||||
.build();
|
||||
```
|
||||
|
||||
(Tested for selenium-webdriver version `2.48.2`)
|
||||
|
||||
The path will be added to the process automatically, you don't need to configure it.
|
||||
But you can get it from `require('chromedriver').path` if you want it.
|
||||
|
||||
## Running via node
|
||||
|
||||
The package exports a `path` string that contains the path to the
|
||||
chromedriver binary/executable.
|
||||
|
||||
Below is an example of using this package via node.
|
||||
|
||||
```javascript
|
||||
var childProcess = require('child_process');
|
||||
var chromedriver = require('chromedriver');
|
||||
var binPath = chromedriver.path;
|
||||
|
||||
var childArgs = [
|
||||
'some argument'
|
||||
];
|
||||
|
||||
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
|
||||
// handle results
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
You can also use the start and stop methods:
|
||||
|
||||
```javascript
|
||||
var chromedriver = require('chromedriver');
|
||||
|
||||
args = [
|
||||
// optional arguments
|
||||
];
|
||||
chromedriver.start(args);
|
||||
// run your tests
|
||||
chromedriver.stop();
|
||||
|
||||
```
|
||||
|
||||
With the latest version, you can optionally receive a Promise from the `chromedriver.start` function:
|
||||
|
||||
```javascript
|
||||
var returnPromise = true;
|
||||
chromedriver
|
||||
.start(args, returnPromise)
|
||||
.then(() => {
|
||||
console.log('chromedriver is ready');
|
||||
});
|
||||
```
|
||||
|
||||
Note: if your tests are ran asynchronously, chromedriver.stop() will have to be
|
||||
executed as a callback at the end of your tests
|
||||
|
||||
## Versioning
|
||||
|
||||
The NPM package version tracks the version of chromedriver that will be installed,
|
||||
with an additional build number that is used for revisions to the installer.
|
||||
You can use the package version number to install a specific version, or use the
|
||||
setting to a specific version. If there is a new Chromedriver version available which is not yet available as a version of `node-chromedriver`, the npm command `npm run update-chromedriver` in this repository can be used to make the required updates to this module, please submit the change as a PR. To always install the latest version of Chromedriver,
|
||||
use `LATEST` as the version number:
|
||||
|
||||
```shell
|
||||
npm install chromedriver --chromedriver_version=LATEST
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
chromedriver_version=LATEST
|
||||
```
|
||||
|
||||
Another option is to use env variable `CHROMEDRIVER_VERSION`.
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_VERSION=LATEST npm install chromedriver
|
||||
```
|
||||
|
||||
You can force the latest release for a specific major version by specifying `LATEST_{VERSION_NUMBER}`:
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_VERSION=LATEST_80 npm install chromedriver
|
||||
```
|
||||
|
||||
You can also force a different version of chromedriver by replacing `LATEST` with a version number:
|
||||
|
||||
```shell
|
||||
CHROMEDRIVER_VERSION=75.0.3770.140 npm install chromedriver
|
||||
```
|
||||
|
||||
## Detect ChromeDriver Version
|
||||
|
||||
The NPM package version may not be always compatible to your Chrome version.
|
||||
To get the chromedriver that corresponds to the version of Chrome installed,
|
||||
you can use the npm config property `detect_chromedriver_version`.
|
||||
|
||||
```shell
|
||||
npm install chromedriver --detect_chromedriver_version
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
detect_chromedriver_version=true
|
||||
```
|
||||
|
||||
Another option is to use environment variable `DETECT_CHROMEDRIVER_VERSION`.
|
||||
|
||||
```shell
|
||||
DETECT_CHROMEDRIVER_VERSION=true npm install chromedriver
|
||||
```
|
||||
|
||||
**Note:** When the property `detect_chromedriver_version` is provided,
|
||||
`chromedriver_version` and `chromedriver_filepath` properties are ignored.
|
||||
|
||||
## Include Chromium
|
||||
|
||||
If you don't have Chrome installed, you can check for Chromium version instead by setting the argument `include_chromium` to `true`.
|
||||
|
||||
```shell
|
||||
npm install chromedriver --include_chromium
|
||||
```
|
||||
|
||||
Or add property into your [`.npmrc`](https://docs.npmjs.com/files/npmrc) file.
|
||||
|
||||
```
|
||||
include_chromium=true
|
||||
```
|
||||
|
||||
Another option is to use environment variable `INCLUDE_CHROMIUM`.
|
||||
|
||||
```shell
|
||||
INCLUDE_CHROMIUM=true npm install chromedriver
|
||||
```
|
||||
|
||||
**Note:** The property `INCLUDE_CHROMIUM` is ignored if the property `DETECT_CHROMEDRIVER_VERSION` is not used.
|
||||
|
||||
## A Note on chromedriver
|
||||
|
||||
Chromedriver is not a library for NodeJS.
|
||||
|
||||
This is an _NPM wrapper_ and can be used to conveniently make ChromeDriver available.
|
||||
It is not a Node.js wrapper.
|
||||
|
||||
## Supported Node.js versions
|
||||
|
||||
We will do our best to support every supported Node.js versions.
|
||||
See [nodejs/Release](https://github.com/nodejs/Release) for
|
||||
the current supported versions. You can also view our
|
||||
[build scripts](https://github.com/giggio/node-chromedriver/blob/main/.github/workflows/build.yml#L41) and check the versions there.
|
||||
|
||||
## Contributing
|
||||
|
||||
Questions, comments, bug reports, and pull requests are all welcome. Submit them at
|
||||
[the project on GitHub](https://github.com/giggio/node-chromedriver/).
|
||||
|
||||
Bug reports that include steps-to-reproduce (including code) are the
|
||||
best. Even better, make them in the form of pull requests.
|
||||
|
||||
We have added
|
||||
[VS Code Remote support with containers](https://code.visualstudio.com/docs/remote/containers).
|
||||
If you are on Windows, set `git config core.autocrlf input` so you don't get git errors.
|
||||
|
||||
## Author
|
||||
|
||||
[Giovanni Bassi](https://github.com/giggio), with collaboration from
|
||||
[lots of good people](https://github.com/giggio/node-chromedriver/graphs/contributors).
|
||||
|
||||
Thanks for Obvious and their PhantomJS project for heavy inspiration! Check their project on [Github](https://github.com/Obvious/phantomjs/).
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the Apache License, Version 2.0.
|
||||
13
node_modules/chromedriver/bin/chromedriver
generated
vendored
Normal file
13
node_modules/chromedriver/bin/chromedriver
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
const path = require("path");
|
||||
const spawn = require("child_process").spawn;
|
||||
const binPath = require(path.join(__dirname, "..", "lib", "chromedriver")).path;
|
||||
const args = process.argv.slice(2);
|
||||
const cp = spawn(binPath, args);
|
||||
cp.stdout.pipe(process.stdout);
|
||||
cp.stderr.pipe(process.stderr);
|
||||
cp.on("exit", process.exit);
|
||||
process.on("SIGTERM", function() {
|
||||
cp.kill("SIGTERM");
|
||||
process.exit(1);
|
||||
});
|
||||
397
node_modules/chromedriver/install.js
generated
vendored
Normal file
397
node_modules/chromedriver/install.js
generated
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
'use strict';
|
||||
// @ts-check
|
||||
|
||||
const fs = require('fs');
|
||||
const helper = require('./lib/chromedriver');
|
||||
const axios = require('axios');
|
||||
const path = require('path');
|
||||
const child_process = require('child_process');
|
||||
const os = require('os');
|
||||
const url = require('url');
|
||||
const https = require('https');
|
||||
const { promisify } = require('util');
|
||||
const { finished } = require('stream');
|
||||
const extractZip = require('extract-zip');
|
||||
const { getChromeVersion } = require('@testim/chrome-version');
|
||||
const HttpsProxyAgent = require('https-proxy-agent');
|
||||
const getProxyForUrl = require("proxy-from-env").getProxyForUrl;
|
||||
const { compareVersions } = require('compare-versions');
|
||||
|
||||
const finishedAsync = promisify(finished);
|
||||
|
||||
const skipDownload = process.env.npm_config_chromedriver_skip_download || process.env.CHROMEDRIVER_SKIP_DOWNLOAD;
|
||||
if (skipDownload === 'true') {
|
||||
console.log('Found CHROMEDRIVER_SKIP_DOWNLOAD variable, skipping installation.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const libPath = path.join(__dirname, 'lib', 'chromedriver');
|
||||
let cdnUrl = process.env.npm_config_chromedriver_cdnurl || process.env.CHROMEDRIVER_CDNURL || 'https://chromedriver.storage.googleapis.com';
|
||||
const configuredfilePath = process.env.npm_config_chromedriver_filepath || process.env.CHROMEDRIVER_FILEPATH;
|
||||
|
||||
// adapt http://chromedriver.storage.googleapis.com/
|
||||
cdnUrl = cdnUrl.replace(/\/+$/, '');
|
||||
const detect_chromedriver_version = process.env.npm_config_detect_chromedriver_version || process.env.DETECT_CHROMEDRIVER_VERSION;
|
||||
const include_chromium = (process.env.npm_config_include_chromium || process.env.INCLUDE_CHROMIUM) === 'true';
|
||||
let chromedriver_version = process.env.npm_config_chromedriver_version || process.env.CHROMEDRIVER_VERSION || helper.version;
|
||||
let chromedriverBinaryFilePath;
|
||||
let downloadedFile = '';
|
||||
let platform = '';
|
||||
|
||||
(async function install() {
|
||||
try {
|
||||
if (detect_chromedriver_version === 'true') {
|
||||
// Refer http://chromedriver.chromium.org/downloads/version-selection
|
||||
const chromeVersion = await getChromeVersion(include_chromium);
|
||||
console.log("Your Chrome version is " + chromeVersion);
|
||||
const versionMatch = /^(.*?)\.\d+$/.exec(chromeVersion);
|
||||
if (versionMatch) {
|
||||
const chromeVersionWithoutPatch = versionMatch[1];
|
||||
await getChromeDriverVersion(getRequestOptions(cdnUrl + '/LATEST_RELEASE_' + chromeVersionWithoutPatch));
|
||||
console.log("Compatible ChromeDriver version is " + chromedriver_version);
|
||||
}
|
||||
}
|
||||
if (chromedriver_version === 'LATEST') {
|
||||
await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE`));
|
||||
} else {
|
||||
const latestReleaseForVersionMatch = chromedriver_version.match(/LATEST_(\d+)/);
|
||||
if (latestReleaseForVersionMatch) {
|
||||
const majorVersion = latestReleaseForVersionMatch[1];
|
||||
await getChromeDriverVersion(getRequestOptions(`${cdnUrl}/LATEST_RELEASE_${majorVersion}`));
|
||||
}
|
||||
}
|
||||
platform = validatePlatform();
|
||||
const tmpPath = findSuitableTempDirectory();
|
||||
const chromedriverBinaryFileName = process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
|
||||
chromedriverBinaryFilePath = path.resolve(tmpPath, chromedriverBinaryFileName);
|
||||
const chromedriverIsAvailable = await verifyIfChromedriverIsAvailableAndHasCorrectVersion();
|
||||
if (!chromedriverIsAvailable) {
|
||||
console.log('Current existing ChromeDriver binary is unavailable, proceeding with download and extraction.');
|
||||
await downloadFile(tmpPath);
|
||||
await extractDownload(tmpPath);
|
||||
}
|
||||
await copyIntoPlace(tmpPath, libPath);
|
||||
fixFilePermissions();
|
||||
console.log('Done. ChromeDriver binary available at', helper.path);
|
||||
} catch (err) {
|
||||
console.error('ChromeDriver installation failed', err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
|
||||
function validatePlatform() {
|
||||
/** @type string */
|
||||
let thePlatform = process.platform;
|
||||
if (thePlatform === 'linux') {
|
||||
if (process.arch === 'arm64' || process.arch === 'x64') {
|
||||
thePlatform += '64';
|
||||
} else {
|
||||
console.log('Only Linux 64 bits supported.');
|
||||
process.exit(1);
|
||||
}
|
||||
} else if (thePlatform === 'darwin' || thePlatform === 'freebsd') {
|
||||
const osxPlatform = getMacOsRealArch();
|
||||
|
||||
if (!osxPlatform) {
|
||||
console.log('Only Mac 64 bits supported.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
thePlatform = osxPlatform;
|
||||
} else if (thePlatform !== 'win32') {
|
||||
console.log('Unexpected platform or architecture:', process.platform, process.arch);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return thePlatform;
|
||||
}
|
||||
|
||||
async function downloadFile(dirToLoadTo) {
|
||||
if (detect_chromedriver_version !== 'true' && configuredfilePath) {
|
||||
downloadedFile = configuredfilePath;
|
||||
console.log('Using file: ', downloadedFile);
|
||||
return;
|
||||
} else {
|
||||
const fileName = `chromedriver_${platform}.zip`;
|
||||
const tempDownloadedFile = path.resolve(dirToLoadTo, fileName);
|
||||
downloadedFile = tempDownloadedFile;
|
||||
const formattedDownloadUrl = `${cdnUrl}/${chromedriver_version}/${fileName}`;
|
||||
console.log('Downloading from file: ', formattedDownloadUrl);
|
||||
console.log('Saving to file:', downloadedFile);
|
||||
await requestBinary(getRequestOptions(formattedDownloadUrl), downloadedFile);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyIfChromedriverIsAvailableAndHasCorrectVersion() {
|
||||
if (!fs.existsSync(chromedriverBinaryFilePath))
|
||||
return Promise.resolve(false);
|
||||
const forceDownload = process.env.npm_config_chromedriver_force_download === 'true' || process.env.CHROMEDRIVER_FORCE_DOWNLOAD === 'true';
|
||||
if (forceDownload)
|
||||
return Promise.resolve(false);
|
||||
console.log('ChromeDriver binary exists. Validating...');
|
||||
const deferred = new Deferred();
|
||||
try {
|
||||
fs.accessSync(chromedriverBinaryFilePath, fs.constants.X_OK);
|
||||
const cp = child_process.spawn(chromedriverBinaryFilePath, ['--version']);
|
||||
let str = '';
|
||||
cp.stdout.on('data', data => str += data);
|
||||
cp.on('error', () => deferred.resolve(false));
|
||||
cp.on('close', code => {
|
||||
if (code !== 0)
|
||||
return deferred.resolve(false);
|
||||
const parts = str.split(' ');
|
||||
if (parts.length < 3)
|
||||
return deferred.resolve(false);
|
||||
if (parts[1].startsWith(chromedriver_version)) {
|
||||
console.log(`ChromeDriver is already available at '${chromedriverBinaryFilePath}'.`);
|
||||
return deferred.resolve(true);
|
||||
}
|
||||
deferred.resolve(false);
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
deferred.resolve(false);
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function findSuitableTempDirectory() {
|
||||
const now = Date.now();
|
||||
const candidateTmpDirs = [
|
||||
process.env.npm_config_tmp,
|
||||
process.env.XDG_CACHE_HOME,
|
||||
// Platform specific default, including TMPDIR/TMP/TEMP env
|
||||
os.tmpdir(),
|
||||
path.join(process.cwd(), 'tmp')
|
||||
];
|
||||
|
||||
for (const tempDir of candidateTmpDirs) {
|
||||
if (!tempDir) continue;
|
||||
const namespace = chromedriver_version;
|
||||
const candidatePath = path.join(tempDir, namespace, 'chromedriver');
|
||||
try {
|
||||
fs.mkdirSync(candidatePath, { recursive: true });
|
||||
const testFile = path.join(candidatePath, now + '.tmp');
|
||||
fs.writeFileSync(testFile, 'test');
|
||||
fs.unlinkSync(testFile);
|
||||
return candidatePath;
|
||||
} catch (e) {
|
||||
console.log(candidatePath, 'is not writable:', e.message);
|
||||
}
|
||||
}
|
||||
console.error('Can not find a writable tmp directory, please report issue on https://github.com/giggio/chromedriver/issues/ with as much information as possible.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function getRequestOptions(downloadPath) {
|
||||
/** @type import('axios').AxiosRequestConfig */
|
||||
const options = { url: downloadPath, method: "GET" };
|
||||
const urlParts = url.parse(downloadPath);
|
||||
const isHttps = urlParts.protocol === 'https:';
|
||||
const proxyUrl = getProxyForUrl(downloadPath);
|
||||
|
||||
if (proxyUrl) {
|
||||
const proxyUrlParts = url.parse(proxyUrl);
|
||||
if (proxyUrlParts.hostname && proxyUrlParts.protocol)
|
||||
options.proxy = {
|
||||
host: proxyUrlParts.hostname,
|
||||
port: proxyUrlParts.port ? parseInt(proxyUrlParts.port) : 80,
|
||||
protocol: proxyUrlParts.protocol
|
||||
};
|
||||
}
|
||||
|
||||
if (isHttps) {
|
||||
// Use certificate authority settings from npm
|
||||
let ca = process.env.npm_config_ca;
|
||||
if (ca)
|
||||
console.log('Using npmconf ca.');
|
||||
|
||||
if (!ca && process.env.npm_config_cafile) {
|
||||
try {
|
||||
ca = fs.readFileSync(process.env.npm_config_cafile, { encoding: 'utf8' });
|
||||
} catch (e) {
|
||||
console.error('Could not read cafile', process.env.npm_config_cafile, e);
|
||||
}
|
||||
console.log('Using npmconf cafile.');
|
||||
}
|
||||
|
||||
if (proxyUrl) {
|
||||
console.log('Using workaround for https-url combined with a proxy.');
|
||||
const httpsProxyAgentOptions = url.parse(proxyUrl);
|
||||
// @ts-ignore
|
||||
httpsProxyAgentOptions.ca = ca;
|
||||
// @ts-ignore
|
||||
httpsProxyAgentOptions.rejectUnauthorized = !!process.env.npm_config_strict_ssl;
|
||||
// @ts-ignore
|
||||
options.httpsAgent = new HttpsProxyAgent(httpsProxyAgentOptions);
|
||||
options.proxy = false;
|
||||
} else {
|
||||
options.httpsAgent = new https.Agent({
|
||||
rejectUnauthorized: !!process.env.npm_config_strict_ssl,
|
||||
ca: ca
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Use specific User-Agent
|
||||
if (process.env.npm_config_user_agent) {
|
||||
options.headers = { 'User-Agent': process.env.npm_config_user_agent };
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('axios').AxiosRequestConfig} requestOptions
|
||||
*/
|
||||
async function getChromeDriverVersion(requestOptions) {
|
||||
console.log('Finding Chromedriver version.');
|
||||
// @ts-expect-error
|
||||
const response = await axios.request(requestOptions);
|
||||
chromedriver_version = response.data.trim();
|
||||
console.log(`Chromedriver version is ${chromedriver_version}.`);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('axios').AxiosRequestConfig} requestOptions
|
||||
* @param {string} filePath
|
||||
*/
|
||||
async function requestBinary(requestOptions, filePath) {
|
||||
const outFile = fs.createWriteStream(filePath);
|
||||
let response;
|
||||
try {
|
||||
// @ts-expect-error
|
||||
response = await axios.request({ responseType: 'stream', ...requestOptions });
|
||||
} catch (error) {
|
||||
if (error && error.response) {
|
||||
if (error.response.status)
|
||||
console.error('Error status code:', error.response.status);
|
||||
if (error.response.data) {
|
||||
error.response.data.on('data', data => console.error(data.toString('utf8')));
|
||||
try {
|
||||
await finishedAsync(error.response.data);
|
||||
} catch (error) {
|
||||
console.error('Error downloading entire response:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error('Error with http(s) request: ' + error);
|
||||
}
|
||||
let count = 0;
|
||||
let notifiedCount = 0;
|
||||
response.data.on('data', data => {
|
||||
count += data.length;
|
||||
if ((count - notifiedCount) > 1024 * 1024) {
|
||||
console.log('Received ' + Math.floor(count / 1024) + 'K...');
|
||||
notifiedCount = count;
|
||||
}
|
||||
});
|
||||
response.data.on('end', () => console.log('Received ' + Math.floor(count / 1024) + 'K total.'));
|
||||
const pipe = response.data.pipe(outFile);
|
||||
await new Promise((resolve, reject) => {
|
||||
pipe.on('finish', resolve);
|
||||
pipe.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
async function extractDownload(dirToExtractTo) {
|
||||
if (path.extname(downloadedFile) !== '.zip') {
|
||||
fs.copyFileSync(downloadedFile, chromedriverBinaryFilePath);
|
||||
console.log('Skipping zip extraction - binary file found.');
|
||||
return;
|
||||
}
|
||||
console.log(`Extracting zip contents to ${dirToExtractTo}.`);
|
||||
try {
|
||||
await extractZip(path.resolve(downloadedFile), { dir: dirToExtractTo });
|
||||
} catch (error) {
|
||||
throw new Error('Error extracting archive: ' + error);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyIntoPlace(originPath, targetPath) {
|
||||
fs.rmSync(targetPath, { recursive: true, force: true });
|
||||
console.log(`Copying from ${originPath} to target path ${targetPath}`);
|
||||
fs.mkdirSync(targetPath);
|
||||
|
||||
// Look for the extracted directory, so we can rename it.
|
||||
const files = fs.readdirSync(originPath, { withFileTypes: true })
|
||||
.filter(dirent => dirent.isFile() && dirent.name.startsWith('chromedriver') && !dirent.name.endsWith(".debug") && !dirent.name.endsWith(".zip"))
|
||||
.map(dirent => dirent.name);
|
||||
const promises = files.map(name => {
|
||||
return /** @type {Promise<void>} */(new Promise((resolve) => {
|
||||
const file = path.join(originPath, name);
|
||||
const reader = fs.createReadStream(file);
|
||||
const targetFile = path.join(targetPath, name);
|
||||
const writer = fs.createWriteStream(targetFile);
|
||||
writer.on("close", () => resolve());
|
||||
reader.pipe(writer);
|
||||
}));
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
|
||||
function fixFilePermissions() {
|
||||
// Check that the binary is user-executable and fix it if it isn't (problems with unzip library)
|
||||
if (process.platform != 'win32') {
|
||||
const stat = fs.statSync(helper.path);
|
||||
// 64 == 0100 (no octal literal in strict mode)
|
||||
if (!(stat.mode & 64)) {
|
||||
console.log('Fixing file permissions.');
|
||||
fs.chmodSync(helper.path, '755');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMacOsRealArch() {
|
||||
if (process.arch === 'arm64' || isEmulatedRosettaEnvironment()) {
|
||||
if (compareVersions(chromedriver_version, '106.0.5249.61') < 0) {
|
||||
return 'mac64_m1';
|
||||
}
|
||||
|
||||
return 'mac_arm64';
|
||||
}
|
||||
|
||||
if (process.arch === 'x64') {
|
||||
return 'mac64';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function isEmulatedRosettaEnvironment() {
|
||||
const archName = child_process.spawnSync('uname', ['-m']).stdout.toString().trim();
|
||||
|
||||
if (archName === 'x86_64') {
|
||||
const proc = child_process.spawnSync('sysctl', ['-in', 'sysctl.proc_translated']);
|
||||
|
||||
// When run with `-in`, the return code is 0 even if there is no `sysctl.proc_translated`
|
||||
if (proc.status) {
|
||||
throw new Error('Unexpected return code from sysctl: ' + proc.status);
|
||||
}
|
||||
|
||||
// If there is no `sysctl.proc_translated` (i.e. not rosetta) then nothing is printed to
|
||||
// stdout
|
||||
if (!proc.stdout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const processTranslated = proc.stdout.toString().trim();
|
||||
|
||||
return processTranslated === '1';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function Deferred() {
|
||||
this.resolve = null;
|
||||
this.reject = null;
|
||||
this.promise = new Promise(function (resolve, reject) {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
}.bind(this));
|
||||
Object.freeze(this);
|
||||
}
|
||||
47
node_modules/chromedriver/lib/chromedriver.js
generated
vendored
Normal file
47
node_modules/chromedriver/lib/chromedriver.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const tcpPortUsed = require('tcp-port-used');
|
||||
function getPortFromArgs(args) {
|
||||
let port = 9515;
|
||||
if (!args) {
|
||||
return port;
|
||||
}
|
||||
const portRegexp = /--port=(\d*)/;
|
||||
const portArg = args.find(function (arg) {
|
||||
return portRegexp.test(arg);
|
||||
});
|
||||
if (portArg) {
|
||||
port = parseInt(portRegexp.exec(portArg)[1]);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
process.env.PATH = path.join(__dirname, 'chromedriver') + path.delimiter + process.env.PATH;
|
||||
exports.path = process.platform === 'win32' ? path.join(__dirname, 'chromedriver', 'chromedriver.exe') : path.join(__dirname, 'chromedriver', 'chromedriver');
|
||||
exports.version = '109.0.5414.74';
|
||||
exports.start = function (args, returnPromise) {
|
||||
let command = exports.path;
|
||||
if (!fs.existsSync(command)) {
|
||||
console.log('Could not find chromedriver in default path: ', command);
|
||||
console.log('Falling back to use global chromedriver bin');
|
||||
command = process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver';
|
||||
}
|
||||
const cp = require('child_process').spawn(command, args);
|
||||
cp.stdout.pipe(process.stdout);
|
||||
cp.stderr.pipe(process.stderr);
|
||||
exports.defaultInstance = cp;
|
||||
if (!returnPromise) {
|
||||
return cp;
|
||||
}
|
||||
const port = getPortFromArgs(args);
|
||||
const pollInterval = 100;
|
||||
const timeout = 10000;
|
||||
return tcpPortUsed.waitUntilUsed(port, pollInterval, timeout)
|
||||
.then(function () {
|
||||
return cp;
|
||||
});
|
||||
};
|
||||
exports.stop = function () {
|
||||
if (exports.defaultInstance != null) {
|
||||
exports.defaultInstance.kill();
|
||||
}
|
||||
};
|
||||
BIN
node_modules/chromedriver/lib/chromedriver/chromedriver.exe
generated
vendored
Normal file
BIN
node_modules/chromedriver/lib/chromedriver/chromedriver.exe
generated
vendored
Normal file
Binary file not shown.
46
node_modules/chromedriver/package.json
generated
vendored
Normal file
46
node_modules/chromedriver/package.json
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "chromedriver",
|
||||
"version": "109.0.0",
|
||||
"keywords": [
|
||||
"chromedriver",
|
||||
"selenium"
|
||||
],
|
||||
"description": "ChromeDriver for Selenium",
|
||||
"homepage": "https://github.com/giggio/node-chromedriver",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/giggio/node-chromedriver.git"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"author": {
|
||||
"name": "Giovanni Bassi",
|
||||
"email": "giggio@giggio.net",
|
||||
"url": "http://www.lambda3.com.br"
|
||||
},
|
||||
"main": "lib/chromedriver",
|
||||
"bin": {
|
||||
"chromedriver": "bin/chromedriver"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node install.js",
|
||||
"update-chromedriver": "node update.js",
|
||||
"typecheck": "tsc",
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@testim/chrome-version": "^1.1.3",
|
||||
"axios": "^1.2.1",
|
||||
"compare-versions": "^5.0.1",
|
||||
"extract-zip": "^2.0.1",
|
||||
"https-proxy-agent": "^5.0.1",
|
||||
"proxy-from-env": "^1.1.0",
|
||||
"tcp-port-used": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.29.0",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user