I use WebDriver.
https://github.com/dom96/webdriver
I want to start firefox headless. Is this possible?
I wrote the following code, and Firefox comes up with a GUI.
import webdriver
import os, osproc
when isMainModule:
let currentPath = getCurrentDir()
let outp = startProcess(currentPath / "geckodriver.exe", "")
echo "awake: ", currentPath / "geckodriver.exe"
echo repr(outp)
var wDriver = newWebDriver()
var session = wDriver.createSession()
session.navigate("https://example.com")
So, adding --headless to startProcess would result in an error.
import webdriver
import os, osproc
when isMainModule:
let currentPath = getCurrentDir()
let outp = startProcess(currentPath / "geckodriver.exe", "", ["--headless"])
echo "awake: ", currentPath / "geckodriver.exe"
echo repr(outp)
var wDriver = newWebDriver()
var session = wDriver.createSession()
session.navigate("https://example.com")
Is there any way? Please let me know if you know.
Thank you.
Thank you very much for introducing a nice library, @yglukhov!
I immediately ran the sample code, but I could not start it with the following error code.
Additional info: "Requested command not found: \'\'. OS error:"
Exception type: [OSError]
Error: execution of an external program failed:
I will report on github.
Thank you very much!
Thank you for your reply!
try using the Chrome web driver. I see. I'll try it!
Thank you very much!
Replace these procs with Dom's WebDriver (and yes, use the chromedriver):
proc newWebDriver*(url: string = "http://localhost:9515"): WebDriver =
WebDriver(url: url.parseUri, client: newHttpClient())
proc createSession*(self: WebDriver, browser :string = "chrome"): Session =
## Creates a new browsing session.
# Check the readiness of the Web Driver.
let resp = self.client.getContent($(self.url / "status"))
let obj = parseJson(resp)
let ready = obj{"value", "ready"}
if ready.isNil():
let msg = "Readiness message does not follow spec"
raise newException(ProtocolException, msg)
if not ready.getBool():
raise newException(WebDriverException, "WebDriver is not ready")
# Create our session.
let sessionReq = %*{"capabilities": {"browserName": browser, "alwaysMatch":{"goog:chromeOptions":{"args":["--headless"]}}}}
let sessionResp = self.client.postContent($(self.url / "session"),
$sessionReq)
let sessionObj = parseJson(sessionResp)
let sessionId = sessionObj{"value", "sessionId"}
if sessionId.isNil():
raise newException(ProtocolException, "No sessionId in response to request")
return Session(id: sessionId.getStr(), driver: self)
I just tested it, works like a charm
Thank you for your code. I immediately downloaded the WebDriver code locally and rewrote it with your code.
However, I couldn't get the text of the element, probably because findElement or some other process was failing.
When I commented out --headless and ran it, I got the browser screen and programmatically got the exact text of the element.
If it's headless, can't we get elements that are updated by JavaScript?
As an example for halonium with headless, here's how to do it with chrome:
import options, os
import halonium
proc main() =
let session = createSession(Chrome, browserOptions=chromeOptions(args=["--headless"]))
session.navigate("https://google.com")
let searchBar = "input[title=\"Search\"]"
let element = session.waitForElement(searchBar).get()
element.sendKeys("clowns", Key.Enter)
let firstATag = session.waitForElement("#search a").get()
firstATag.click()
sleep(1000)
session.stop()
main()
@b3liever @jyapayne Thank you for your reply!
I try halonium and run @jyapayne 's code. It worked just the way I wanted it to!
Thank you very much.
If I wanted to, could I start the chrome driver in hidden mode?
@mnahito You could not before, but I've just added the ability to in version 0.2.5. Please update to the latest version and then you can hide the chrome driver console like this:
import halonium
proc main() =
# hideChromeDriverConsole and headless give a completely background execution on Windows
let session = createSession(
Chrome, browserOptions=chromeOptions(args=["--headless"]), hideChromeDriverConsole=true
)
# rest of your code
main()