tebeka / selenium

Selenium/Webdriver client for Go
MIT License
2.51k stars 410 forks source link

Example required how to start firefox via geckodriver without selenium java server #221

Open vodolaz095 opened 3 years ago

vodolaz095 commented 3 years ago

How can you start this package with firefox on linux?

I'll be very gratefull for minimal working example for firefox like this one as provided for https://www.npmjs.com/package/selenium-webdriver package:


const {Builder, By, Key, until} = require('selenium-webdriver');

(async function example() {
  let driver = await new Builder().forBrowser('firefox').build();
  try {
    await driver.get('http://www.google.com/ncr');
    await driver.findElement(By.name('q')).sendKeys('webdriver', Key.RETURN);
    await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
  } finally {
    await driver.quit();
  }
})();

It starts new firefox browser instance in my X.org GUI via geckodriver, so i can see browser running as one of windows.

dan-r95 commented 3 years ago

Hey, did you find a solution?

sunshine69 commented 3 years ago

My sample like this and it works

package main

import (
    "fmt"
    "os"
    "strings"
    "time"
    "github.com/tebeka/selenium"
)

func main() {
    // Start a Selenium WebDriver server instance (if one is not already
    // running).
    var (
        // These paths will be different on your system.
        // seleniumPath    = "vendor/selenium-server-standalone-3.4.jar"
        // geckoDriverPath = "vendor/geckodriver-v0.18.0-linux64"
        geckoDriverPath = os.Getenv("HOME") +  "/.local/bin/geckodriver"
        port            = 4444
    )
    opts := []selenium.ServiceOption{
        selenium.StartFrameBuffer(),           // Start an X frame buffer for the browser to run in.
        selenium.GeckoDriver(geckoDriverPath), // Specify the path to GeckoDriver in order to use Firefox.
        selenium.Output(os.Stderr),            // Output debug information to STDERR.
    }
    selenium.SetDebug(true)
    service, err := selenium.NewGeckoDriverService(geckoDriverPath, port, opts[0])
    if err != nil {
        panic(err) // panic is used only as an example and is not otherwise recommended.
    }
    defer service.Stop()

    // Connect to the WebDriver instance running locally.
    caps := selenium.Capabilities{"browserName": "firefox"}
    wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d", port))
    // wd, err := selenium.NewRemote(caps, "")
    if err != nil {
        panic(err)
    }
    defer wd.Quit()

    // Navigate to the simple playground interface.
    if err := wd.Get("http://play.golang.org/?simple=1"); err != nil {
        panic(err)
    }

    // Get a reference to the text box containing code.
    elem, err := wd.FindElement(selenium.ByCSSSelector, "#code")
    if err != nil {
        panic(err)
    }
    // Remove the boilerplate code already in the text box.
    if err := elem.Clear(); err != nil {
        panic(err)
    }

    // Enter some new code in text box.
    err = elem.SendKeys(`
        package main
        import "fmt"

        func main() {
            fmt.Println("Hello WebDriver!\n")
        }
    `)
    if err != nil {
        panic(err)
    }

    // Click the run button.
    btn, err := wd.FindElement(selenium.ByCSSSelector, "#run")
    if err != nil {
        panic(err)
    }
    if err := btn.Click(); err != nil {
        panic(err)
    }

    // Wait for the program to finish running and get the output.
    outputDiv, err := wd.FindElement(selenium.ByCSSSelector, "#output")
    if err != nil {
        panic(err)
    }

    var output string
    for {
        output, err = outputDiv.Text()
        if err != nil {
            panic(err)
        }
        if output != "Waiting for remote server..." {
            break
        }
        time.Sleep(time.Millisecond * 100)
    }

    fmt.Printf("%s", strings.Replace(output, "\n\n", "\n", -1))

    // Example Output:
    // Hello WebDriver!
    //
    // Program exited.
}
sunshine69 commented 3 years ago

However mine one using Xvfb, you may need to change it so it can use desktop FF, I have not tested it yet.

mdanialr commented 2 years ago

I usually use this:

package main

import (
    "fmt"
    "log"

    "github.com/tebeka/selenium"
)

const (
    DriverPath = "/full/path/to/chromedriver"
    Port       = 9559 // you can use any unused port e.g 8008
)

func main() {
    // 1. Enable selenium service
    // Set the option of the selium service to null. Or set as needed.
    ops := []selenium.ServiceOption{}
    service, err := selenium.NewChromeDriverService(DriverPath, Port, ops...)
    if err != nil {
        log.Panicln("error starting the ChromeDriver server:", err)
    }
    defer service.Stop()

    // 2. Spawn browser
    caps := selenium.Capabilities{"browserName": "chrome"}
    // call browser urlPrefix: “http://127.0.0.1:PORT/wd/hub“ is mandatory.
    wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://127.0.0.1:%d/wd/hub", Port))
    if err != nil {
        log.Panicln("error spawning browser:", err)
    }
    defer wd.Quit()

    // 3. Do the job
        // you can do something here

    log.Println("DONE & Life is good")
}

you can use selenium.NewSeleniumService and change DriverPath to where selenium-server-x.x.x.jar exists. Notes: don't forget to install JAVA. Otherwise, it will give you something like:

error starting the ChromeDriver server: exec: "java": executable file not found in $PATH
panic: error starting the ChromeDriver server: exec: "java": executable file not found in $PATH

Since I don't wanna install JAVA so I stick to using chrome and chromedriver instead.

Credits: https://programming.vip/docs/golang-uses-selenium-to-operate-chrome.html