Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

firstMatch vs alwaysMatch Capabilities #129

Open
brianbruggeman opened this issue Mar 19, 2021 · 3 comments
Open

firstMatch vs alwaysMatch Capabilities #129

brianbruggeman opened this issue Mar 19, 2021 · 3 comments

Comments

@brianbruggeman
Copy link

Am I correct in assuming that fantoccini only supports sending alwaysMatch?

The ClientBuilder struct itself only provides a way to add "capabilities", which I would have expected follows the webdriver standard: https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities

As noted on that page, the general structure looks like this for always match:

{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "firefox",
      "browserVersion": "60"
    }
  }
}

And looks like this for first match:

{
  "capabilities": {
    "firstMatch": [
      {"platformName": "macos"},
      {"platformName": "linux"}
    ]
  }
}

And of course, the two can be combined:

{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "firefox",
      "moz:firefoxOptions": {
        "profile": "<base64 encoded profile>",
        "args": ["-headless"],
        "prefs": {"dom.ipc.processCount": 8},
        "log":{"level": "trace"}
      }
    },
    "firstMatch": [
      {"platformName": "macos"},
      {"platformName": "linux"}
    ]
  }
}

But digging in the Session code and ClientBuilder code, it seems that fantoccini only provides a way of setting: capabilities -> alwaysMatch.

I was kind of hoping for something more like this:

...
let client = ClientBuilder::native()
    .with_always_match(always_match_capabilities)
    .with_first_match(first_match_capabilities)
    .connect(&url)
    .await?;
...

or alternatively:

let client = ClientBuilder::native()
    .with_capabilities(r#"""
    {
      "capabilities": {
        "alwaysMatch": {
          "browserName": "firefox",
          "moz:firefoxOptions": {
            "profile": "<base64 encoded profile>",
            "args": ["-headless"],
            "prefs": {"dom.ipc.processCount": 8},
            "log":{"level": "trace"}
          }
        },
        "firstMatch": [
          {"platformName": "macos"},
          {"platformName": "linux"}
        ]
      }
    }
    """)
    .connect(&url)
    .await?;
@jonhoo
Copy link
Owner

jonhoo commented Mar 21, 2021

Yes, you're right, currently you can only provide alwaysMatch. Part of the reason for that is that we have to match both the old Selenium-based "spec" and the official WebDriver spec, and they don't entirely agree on how these capabilities should work 😅 But I suspect it's probably doable to find a nice abstraction to cover both.

I'm not a huge fan of the version where you give the raw JSON, since it makes it harder for us to inject our own parameters, which is sometimes needed. We could parse it and then inject, but I don't know that that's really any nicer. A sort of builder API for capabilities might work really well though! Want to take a stab at implementing that?

@brianbruggeman
Copy link
Author

Thanks for getting back to me. I'm trying to automate a vaccine signup page, and I want it to run on Windows, Mac and Linux with various versions of Firefox (given multiple end-users).

I think the builder would be rather straight-forward to update and it could be updated in a way that it doesn't change compatibility with the current API. That said, it may be a bit before I have some time to work on this.

That said, when I was working with this over the weekend, I kind of wanted 100% control so I could sideline any extra pieces that fantoccini adds, which is why I mention that second interface. Some of that is because this is all new for me, and I don't know where the edges are. Some of it is so I can isolate my configuration and know that I didn't add it correctly. As an example, I couldn't seem to find a way to get the moz::firefoxOptions to work with headless and/or profile, even though Google seemed to think they should. I was left trying to answer the question: did I make a mistake or is this unsupported? I still don't really have an answer there.

@jonhoo
Copy link
Owner

jonhoo commented Mar 23, 2021

All good --- take your time!

In general, fantoccini doesn't really do anything special with the capabilities you pass in beyond passing them wrapped in whatever the appropriate context are for session creation (see the Selenium spec vs the WebDriver spec).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants