ik1ne / webdriver-downloader Goto Github PK
View Code? Open in Web Editor NEWCli Interface&Library for webdriver download.
License: MIT License
Cli Interface&Library for webdriver download.
License: MIT License
Currently, there's no way to verify driver without using clone().
let driver_path = ...;
let driver_info = ChromedriverInfo::new(driver_path.clone(), browser_path);
if = driver_info.verify_driver(driver_path).await.is_err() {
driver_info.download_verify_install(5).await?;
}
If we add is_installed to WebdriverInfo, this can be improved.
https://github.com/ik1ne/webdriver-downloader/actions/runs/5653813026/job/15315644707
Trying url for version 114.0.5735+90: https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_win32.zip. Verification failed: Failed to connect to driver: webdriver server did not respond: error trying to connect: tcp connect error: No connection could be made because the target machine actively refused it. (os error 10061).
Windows CI sometimes fails even though the tests run fine on local machine.
Currently, some errors are not being displayed properly due to its return types being ().
We should use thiserror to notify end users with detailed information.
Related: #27.
Mockall requires 'static lifetime bound for mocking generics.
Removing Mockall will relieve this requirement, leading to more relaxed lifetime management.
If chromedriver is being verified by root user, the argument --no-sandbox
has to be passed in order for the chrome to launch properly.
Current version of webdriver-downloader does not add that argument even if the user is root, making root user runs without --no-verify
fail.
There is a slight random delay for webdriver initialization, in other words it takes some time for the webdriver to open ports.
This random delay causes the verification process fail because the port is not open yet.
Replace std::thread::sleep
with async_std::task::sleep
or tokio::time::sleep
.
It would be better to add cargo feature so users can decide which runtime to use.
Currently, cli and lib are in same crate which results to mixed dependency.
By separating cli and lib as individual crates, we can minimize dependency required for each crate.
Hi,
I've been trying to create a Dockerfile
that would allow to create a container for chromedriver
service. However, I've been struggling to do so due to various errors coming from chromedriver
.
Invalid port. Exiting...
comes if I try to supply a port via the --port
flag.[1706912416.181][SEVERE]: bind() failed: Address not available (99)
[1706912416.181][INFO]: listen on IPv6 failed with error ERR_ADDRESS_INVALID
, which despite being followed by ChromeDriver was started successfully.
still doesn't let me use the chromedriver
.
I've tried supplying --shm-size=1gb
to docker run
, as suggested in one of the answers for "How to fix "[SEVERE]: bind() failed: Cannot assign requested address (99)" while starting chromedriver" Stack Overflow question but the connection was actively refused. I tried to supply --allowed-origins=*
to chromedriver
but it didn't help.
Q: Could there be a problem with network access because chromedriver
accepts only local connections by default?
I tried to run the docker image with docker build -t app . && docker run --network="host" --rm app & docker rmi app
but it didn't work.
Usually, I ran the container with docker build -t app . && docker run -p 9515:9515 --rm app & docker rmi app
You can find my current Dockerfile
in https://github.com/JohnScience/chromium-chromedriver.
In case the users want to skip the verification of the downloaded driver, we can support --skip-verification option to download only one version and exit early.
webdriver-downloader crate should provide following feature flags: default
, native-tls
, rustls-tls
.
The following changes should be made:
fantoccini
, reqwest
should be changed to optional dependency without default features.default
feature of webdriver-downloader crate should be native-tls
.fantoccini
and reqwest
are not compiled and the default implementation of WebdriverVerificationInfo::verify_driver
and WebdriverInstallationInfo::download_in_tempdir
is erased.native-tls
is enabled(regardless of rustls-tls
).rustls-tls
is enabled and native-tls
is not enabled.Replace "C:\Program Files" with %ProgramFiles(x86)%.
WebdriverVerificationInfo::verify_driver
always run webdriver to check if it's properly installed.
However, in most circumstances it's enough to compare major versions instead of actually running it.
Adding lightweight verification process which only uses webdriver --version
would be helpful for frequent verify_driver
calls.
I'm trying to use webdriver-downloader-cli
in a Docker image created from alpine
. However, I'm getting some weird errors.
In order to track the error in the Docker image build, I made some patches that can be found in https://github.com/JohnScience/webdriver-downloader/commits/debugging/.
The branch of my project that demonstrates the weird behavior is available at https://github.com/JohnScience/booking-rooms/tree/issue_with_webdriver_downloader.
If you try to run docker build .
, you will see something like...
...
=> CACHED [runtime 4/5] COPY --from=builder /webdriver-downloader/target/x86_64-unknown-linux-musl/release/webdriver-downloader /bin/web 0.0s
=> ERROR [runtime 5/5] RUN webdriver-downloader --type chrome --driver /bin/chromedriver 18.1s
------
> [runtime 5/5] RUN webdriver-downloader --type chrome --driver /bin/chromedriver:
1.511 Driver path does not exist: "/bin/chromedriver"
1.580 0: webdriver_downloader::traits::verification_info::WebdriverVerificationInfo::verify_driver::{{closure}}
1.580 1: <T as webdriver_downloader::traits::webdriver_download_info::WebdriverDownloadInfo>::is_installed::{{closure}}
1.580 2: webdriver_downloader::main::{{closure}}
1.580 3: tokio::runtime::scheduler::current_thread::Context::enter
1.580 4: tokio::runtime::context::scoped::Scoped<T>::set
1.580 5: tokio::runtime::runtime::Runtime::block_on
1.580 6: webdriver_downloader::main
1.580 7: std::sys_common::backtrace::__rust_begin_short_backtrace
1.580 8: std::rt::lang_start::{{closure}}
1.580 9: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:284:13
1.580 10: std::panicking::try::do_call
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:552:40
1.580 11: std::panicking::try
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:516:19
1.580 12: std::panic::catch_unwind
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panic.rs:142:14
1.580 13: std::rt::lang_start_internal::{{closure}}
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/rt.rs:148:48
1.580 14: std::panicking::try::do_call
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:552:40
1.580 15: std::panicking::try
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:516:19
1.580 16: std::panic::catch_unwind
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panic.rs:142:14
1.580 17: std::rt::lang_start_internal
1.580 at ./rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/rt.rs:148:20
1.580 18: std::rt::lang_start
1.580
2.257 Trying url for version 121.0.6167+85: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/121.0.6167.85/linux64/chromedriver-linux64.zip.
5.231 Driver path exists: "/tmp/.tmp9gUtfB/chromedriver"
5.234 Verification failed: Failed to start driver: No such file or directory (os error 2).
5.246 Trying url for version 123.0.6273+0: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/123.0.6273.0/linux64/chromedriver-linux64.zip.
8.097 Driver path exists: "/tmp/.tmpIf7vVT/chromedriver"
8.097 Verification failed: Failed to start driver: No such file or directory (os error 2).
8.111 Trying url for version 122.0.6261+18: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/122.0.6261.18/linux64/chromedriver-linux64.zip.
10.86 Driver path exists: "/tmp/.tmpbujs51/chromedriver"
10.87 Verification failed: Failed to start driver: No such file or directory (os error 2).
10.88 Trying url for version 120.0.6099+109: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/120.0.6099.109/linux64/chromedriver-linux64.zip.
13.87 Driver path exists: "/tmp/.tmpueXEzI/chromedriver"
13.87 Verification failed: Failed to start driver: No such file or directory (os error 2).
13.88 Trying url for version 119.0.6045+105: https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/119.0.6045.105/linux64/chromedriver-linux64.zip.
17.91 Driver path exists: "/tmp/.tmpKMvIWQ/chromedriver"
17.91 Verification failed: Failed to start driver: No such file or directory (os error 2).
17.94 Error: Tried 5 possible versions, but no version passed verification.
------
Dockerfile:37
--------------------
35 | COPY --from=builder /webdriver-downloader/target/x86_64-unknown-linux-musl/release/webdriver-downloader /bin/webdriver-downloader
36 |
37 | >>> RUN webdriver-downloader --type chrome --driver /bin/chromedriver
38 |
39 | CMD ["chromedriver", "--version"]
--------------------
ERROR: failed to solve: process "/bin/sh -c webdriver-downloader --type chrome --driver /bin/chromedriver" did not complete successfully: exit code: 1
Error response from daemon: No such image: app:latest
Note that the backtrace in the output comes not from a panic but from a println!("{}", std::backtrace::Backtrace::force_capture())
and has nothing to do with the problem at hand. Based on what I've found, the actual problem happens in the following piece of code:
/// Provides information for verifying a webdriver.
#[async_trait]
pub trait WebdriverVerificationInfo {
/// Capabilities to use for verification.
/// Some driver options such as browser path can be provided by capabilities.
fn driver_capabilities(&self) -> Option<Capabilities>;
/// Verifies driver using [`Self::test_client`].
async fn verify_driver<P: AsRef<Path> + Sync>(
&self,
driver_path: &P,
) -> Result<(), VerificationError> {
let port = get_random_available_port();
if !driver_path.as_ref().exists() {
println!("Driver path does not exist: {:?}", driver_path.as_ref());
println!("{}", std::backtrace::Backtrace::force_capture());
} else {
println!("Driver path exists: {:?}", driver_path.as_ref());
}
let mut child = tokio::process::Command::new(OsStr::new(driver_path.as_ref()))
.arg(&format!("--port={}", port))
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.kill_on_drop(true)
.spawn()?;
println!("Unreachable code");
// ...
}
// ...
}
Somehow, driver_path.as_ref().exists()
evaluates to true while
let mut child = tokio::process::Command::new(OsStr::new(driver_path.as_ref()))
.arg(&format!("--port={}", port))
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.kill_on_drop(true)
.spawn()?;
returns the std::io::Error
error with No such file or directory (os error 2)
via the ?
syntax.
WebdriverVerificationInfo::verify_driver always uses port number 4444.
If webdriver didn't exit successfully for some reason, next run of webdriver-downloader will always fail.
Using a random port instead of fixed one should solve this problem.
It's tedious to find default path when using the lib.
Moving the default path finding logics to lib will solve this.
Add support for linux, Mac
There is only testcases for default feature flags.
We should add testcase for other feature flags too.
Instead of formatting browser_path.display(), we should properly pass arguments as Path on Windows Powershell.
https://developer.chrome.com/blog/chrome-for-testing/
Google Chrome 116 and newer versions do not support chromedriver, instead Google Chrome for Testing should be used.
If there's multiple versions of same major version(for example, 110.0.5, 110.0.6, 110.0,7) all versions will be tried.
We should try one version with the highest minor version and skip the rest.
In webdriver-downloader/webdriver-downloader/src/os_specific/chromedriver/linux.rs at line 10, "chromium" boot name is not supported. This leads to an initialization error:
thread 'main' panicked at 'called Result::unwrap()
on an Err
value: Which(CannotFindBinaryPath)',
In the archlinux environment, the default installation through the package manager points to "chromium"
Although webdriver-downloader itself does not depend on tokio runtime(it only uses tokio features that are runtime independent), fantoccini depends on tokio runtime.
So we should explain that webdriver-downloader must be run on tokio runtime.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.