mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
54694c4fca
* [MISC] Ignore errcheck recommendations for legacy code Some of this is likely intended to stay how it is, some could use refactoring, for now we will mark is and ignore it from the linter to be potentially addressed in the future. * [MISC] Ensure files are gofmt-ed
194 lines
5.4 KiB
Go
194 lines
5.4 KiB
Go
package suites
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/tebeka/selenium"
|
|
"github.com/tebeka/selenium/chrome"
|
|
)
|
|
|
|
// WebDriverSession binding a selenium service and a webdriver.
|
|
type WebDriverSession struct {
|
|
service *selenium.Service
|
|
WebDriver selenium.WebDriver
|
|
}
|
|
|
|
// StartWebDriverWithProxy create a selenium session
|
|
func StartWebDriverWithProxy(proxy string, port int) (*WebDriverSession, error) {
|
|
service, err := selenium.NewChromeDriverService("/usr/bin/chromedriver", port)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
browserPath := os.Getenv("BROWSER_PATH")
|
|
if browserPath == "" {
|
|
browserPath = "/usr/bin/chromium-browser"
|
|
}
|
|
|
|
chromeCaps := chrome.Capabilities{
|
|
Path: browserPath,
|
|
}
|
|
|
|
chromeCaps.Args = append(chromeCaps.Args, "--ignore-certificate-errors")
|
|
|
|
if os.Getenv("HEADLESS") != "" {
|
|
chromeCaps.Args = append(chromeCaps.Args, "--headless")
|
|
chromeCaps.Args = append(chromeCaps.Args, "--no-sandbox")
|
|
}
|
|
|
|
if proxy != "" {
|
|
chromeCaps.Args = append(chromeCaps.Args, fmt.Sprintf("--proxy-server=%s", proxy))
|
|
}
|
|
|
|
caps := selenium.Capabilities{}
|
|
caps.AddChrome(chromeCaps)
|
|
|
|
wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", port))
|
|
if err != nil {
|
|
service.Stop() //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
panic(err)
|
|
}
|
|
|
|
return &WebDriverSession{
|
|
service: service,
|
|
WebDriver: wd,
|
|
}, nil
|
|
}
|
|
|
|
// StartWebDriver create a selenium session
|
|
func StartWebDriver() (*WebDriverSession, error) {
|
|
return StartWebDriverWithProxy("", 4444)
|
|
}
|
|
|
|
// Stop stop the selenium session
|
|
func (wds *WebDriverSession) Stop() error {
|
|
err := wds.WebDriver.Quit()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return wds.service.Stop()
|
|
}
|
|
|
|
// WithWebdriver run some actions against a webdriver
|
|
func WithWebdriver(fn func(webdriver selenium.WebDriver) error) error {
|
|
wds, err := StartWebDriver()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer wds.Stop() //nolint:errcheck // TODO: Legacy code, consider refactoring time permitting.
|
|
|
|
return fn(wds.WebDriver)
|
|
}
|
|
|
|
// Wait wait until condition holds true
|
|
func (wds *WebDriverSession) Wait(ctx context.Context, condition selenium.Condition) error {
|
|
done := make(chan error, 1)
|
|
go func() {
|
|
done <- wds.WebDriver.Wait(condition)
|
|
}()
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
return errors.New("waiting timeout reached")
|
|
case err := <-done:
|
|
return err
|
|
}
|
|
}
|
|
|
|
func (wds *WebDriverSession) waitElementLocated(ctx context.Context, t *testing.T, by, value string) selenium.WebElement {
|
|
var el selenium.WebElement
|
|
err := wds.Wait(ctx, func(driver selenium.WebDriver) (bool, error) {
|
|
var err error
|
|
el, err = driver.FindElement(by, value)
|
|
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "no such element") {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|
|
|
|
return el != nil, nil
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, el)
|
|
return el
|
|
}
|
|
|
|
func (wds *WebDriverSession) waitElementsLocated(ctx context.Context, t *testing.T, by, value string) []selenium.WebElement {
|
|
var el []selenium.WebElement
|
|
err := wds.Wait(ctx, func(driver selenium.WebDriver) (bool, error) {
|
|
var err error
|
|
el, err = driver.FindElements(by, value)
|
|
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "no such element") {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|
|
|
|
return el != nil, nil
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, el)
|
|
return el
|
|
}
|
|
|
|
// WaitElementLocatedByID wait an element is located by id
|
|
func (wds *WebDriverSession) WaitElementLocatedByID(ctx context.Context, t *testing.T, id string) selenium.WebElement {
|
|
return wds.waitElementLocated(ctx, t, selenium.ByID, id)
|
|
}
|
|
|
|
// WaitElementLocatedByTagName wait an element is located by tag name
|
|
func (wds *WebDriverSession) WaitElementLocatedByTagName(ctx context.Context, t *testing.T, tagName string) selenium.WebElement {
|
|
return wds.waitElementLocated(ctx, t, selenium.ByTagName, tagName)
|
|
}
|
|
|
|
// WaitElementLocatedByClassName wait an element is located by class name
|
|
func (wds *WebDriverSession) WaitElementLocatedByClassName(ctx context.Context, t *testing.T, className string) selenium.WebElement {
|
|
return wds.waitElementLocated(ctx, t, selenium.ByClassName, className)
|
|
}
|
|
|
|
// WaitElementLocatedByLinkText wait an element is located by link text
|
|
func (wds *WebDriverSession) WaitElementLocatedByLinkText(ctx context.Context, t *testing.T, linkText string) selenium.WebElement {
|
|
return wds.waitElementLocated(ctx, t, selenium.ByLinkText, linkText)
|
|
}
|
|
|
|
// WaitElementLocatedByCSSSelector wait an element is located by class name
|
|
func (wds *WebDriverSession) WaitElementLocatedByCSSSelector(ctx context.Context, t *testing.T, cssSelector string) selenium.WebElement {
|
|
return wds.waitElementLocated(ctx, t, selenium.ByCSSSelector, cssSelector)
|
|
}
|
|
|
|
// WaitElementsLocatedByCSSSelector wait an element is located by CSS selector
|
|
func (wds *WebDriverSession) WaitElementsLocatedByCSSSelector(ctx context.Context, t *testing.T, cssSelector string) []selenium.WebElement {
|
|
return wds.waitElementsLocated(ctx, t, selenium.ByCSSSelector, cssSelector)
|
|
}
|
|
|
|
// WaitElementTextContains wait the text of an element contains a pattern
|
|
func (wds *WebDriverSession) WaitElementTextContains(ctx context.Context, t *testing.T, element selenium.WebElement, pattern string) {
|
|
err := wds.Wait(ctx, func(driver selenium.WebDriver) (bool, error) {
|
|
text, err := element.Text()
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return strings.Contains(text, pattern), nil
|
|
})
|
|
require.NoError(t, err)
|
|
}
|