Comments (7)
Added in v0.27.2
🙂
from thirtyfour.
Awesome. I have some more changes I need to make to it, to make it more robust. For example currently it assumes there are no tabs already open, and that handles[1] is the new tab. Also I'd like to add a doctest for it.
I think it probably also needs a warning that this will temporarily switch the context to another tab so any selenium operations executed during this time will point at the new tab and not the existing one (in case someone tries using threads or join! etc).
from thirtyfour.
There isn't really a good use case for accessing the same WebDriver in multiple threads. Potentially if you were just reading elements in parallel from a static page that might be ok, but I'd consider that an edge case. So probably this doesn't need a warning for that.
from thirtyfour.
I agree that this would be a pretty handy thing to have. I think the issues you mentioned could be similar the issues I had getting the ElementQuery and ElementWaiter closures to work, so maybe there could be a nice solution.
from thirtyfour.
@bcpeinhardt Thanks to your code above I was able to implement this in WebDriverCommands
.
The trick to getting the closure working seemed to be requiring a Send
trait bound on all of the generic params like this:
async fn in_new_tab<F, Fut, T>(&self, f: F) -> WebDriverResult<T>
where
F: FnOnce() -> Fut + Send,
Fut: Future<Output = WebDriverResult<T>> + Send,
T: Send,
See the in_new_tab
branch. I was able to do the following in a quick test (not included in the branch):
let t = driver.in_new_tab(|| async {
driver.get("https://www.google.com").await?;
sleep(Duration::from_secs(5)).await;
driver.title().await
}).await?;
println!("Window title: {}", t);
Of course you can return Ok(())
from the async block as well, but this was to demonstrate passing a value back out.
The sleep was just so I could confirm that it works correctly.
Let me know if this works for you, and if so I can merge it in 🙂
from thirtyfour.
TOML
[package]
name = "testing_in_new_tab_web_command"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
thirtyfour = { git = "https://github.com/stevepryde/thirtyfour.git", branch = "in_new_tab"}
tokio = "1.12.0"
Code
use thirtyfour::prelude::*;
use tokio;
#[tokio::main]
async fn main() -> WebDriverResult<()> {
let caps = DesiredCapabilities::firefox();
let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps).await?;
let stars_count = driver
.in_new_tab(|| async {
driver
.get("https://github.com/stevepryde/thirtyfour")
.await?;
let stars = driver
.query(By::XPath("//a[@class=\"social-count js-social-count\"]"))
.first()
.await?
.text()
.await?;
Ok(stars)
})
.await?;
println!(
"Thirtyfour has {} stars on github, a number which will likely grow.",
stars_count
);
driver.quit().await?;
Ok(())
}
Works like a charm!!!! This is great, thank you!!!!!
from thirtyfour.
Yup! Out of curiosity, what is the use case for accessing the same &WebDriver in multiple threads? In a sense, the WebDriver commands "mutate" the browser when they click a link or navigate to a new url etc, even though they have an &self in their function signatures. Combining that with the conversation we had before, where you mentioned that Selenium calls from the same driver are returned FIFO rather than asynchronously, I'm not sure what the use case for accessing the same &WebDriver across threads is.
It would be interesting if there were a way to specify setup up and tear down as blocking operations for entry and exit from a thread. In this case one would want Wake -> Switch to named handle (can drivers store named handles?) -> Make Progress -> Switch to previous handle -> Yield. I suspect a setup like this could be achieved with some funky nested threading.
from thirtyfour.
Related Issues (20)
- Error while clicking element. HOT 4
- `#shadow-root` doesn't work on Firefox with geckodriver HOT 1
- Connection refused when using containers HOT 4
- How to use selenium-manager in my code? HOT 2
- thread 'tokio-runtime-worker' panicked at 'internal error: entered unreachable code: received unknown error (no such frame) for NOT_FOUND status code' HOT 4
- How can I set the user-agent for Chromedriver? HOT 3
- Is there a way to use wait_until or something like it to way for a specific ID to be available ? HOT 2
- wait until element to disappear HOT 6
- Chrome Options example erroring HOT 2
- Does `query` work on child elements? HOT 3
- Cannot interact with WebElement HOT 1
- How to trigger onchange event without submitting the form? HOT 2
- How to set PageLoadStrategy::None in DesiredCapabilities::chrome()? HOT 1
- Running the Test without Existing Browser (HtmlUnitDriver) HOT 1
- Add cdp type from auto_generate_cdp crate HOT 2
- How to handle file picker? HOT 4
- How to capture the Chromium's requests and responses traffic using thirtyfour HOT 5
- Maintenance Status
- Device Farm incompatibility - with workaround
- Chromedriver - http incompatibility with hyper HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from thirtyfour.