From 73c0cd0b58c0b57fc3a0a209f59e5eb9c926adfa Mon Sep 17 00:00:00 2001 From: Roman Belyakovsky Date: Fri, 31 Mar 2017 12:45:00 +0200 Subject: [PATCH] Initial commit --- Makefile | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 18 +++++++ main.go | 81 ++++++++++++++++++++++++++++ main_test.go | 41 ++++++++++++++ 4 files changed, 288 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 main.go create mode 100644 main_test.go diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..81918f5 --- /dev/null +++ b/Makefile @@ -0,0 +1,148 @@ +TARGET = selenium-check +BUILDDIR = build +ARCHIVEDIR = archive + +android.arm: GOOS=android +darwin.386: GOOS=darwin +darwin.amd64: GOOS=darwin +darwin.arm: GOOS=darwin +darwin.arm64: GOOS=darwin +dragonfly.amd64: GOOS=dragonfly +freebsd.386: GOOS=freebsd +freebsd.amd64: GOOS=freebsd +freebsd.arm: GOOS=freebsd +linux.386: GOOS=linux +linux.amd64: GOOS=linux +linux.arm: GOOS=linux +linux.arm64: GOOS=linux +linux.ppc64: GOOS=linux +linux.ppc64le: GOOS=linux +linux.mips: GOOS=linux +linux.mipsle: GOOS=linux +linux.mips64: GOOS=linux +linux.mips64le: GOOS=linux + +netbsd.386: GOOS=netbsd +netbsd.amd64: GOOS=netbsd +netbsd.arm: GOOS=netbsd +openbsd.386: GOOS=openbsd +openbsd.amd64: GOOS=openbsd +openbsd.arm: GOOS=openbsd +plan9.386: GOOS=plan9 +plan9.amd64: GOOS=plan9 +solaris.amd64: GOOS=solaris +windows.386: GOOS=windows +windows.amd64: GOOS=windows +android.arm: GOARCH=arm +darwin.386: GOARCH=386 +darwin.amd64: GOARCH=amd64 +darwin.arm: GOARCH=arm +darwin.arm64: GOARCH=arm64 +dragonfly.amd64: GOARCH=amd64 +freebsd.386: GOARCH=386 +freebsd.amd64: GOARCH=amd64 +freebsd.arm: GOARCH=arm +linux.386: GOARCH=386 +linux.amd64: GOARCH=amd64 +linux.arm: GOARCH=arm +linux.arm64: GOARCH=arm64 +linux.ppc64: GOARCH=ppc64 +linux.ppc64le: GOARCH=ppc64le +linux.mips: GOARCH=mips +linux.mipsle: GOARCH=mipsle +linux.mips64: GOARCH=mips64 +linux.mips64le: GOARCH=mips64le +netbsd.386: GOARCH=386 +netbsd.amd64: GOARCH=amd64 +netbsd.arm: GOARCH=arm +openbsd.386: GOARCH=386 +openbsd.amd64: GOARCH=amd64 +openbsd.arm: GOARCH=arm +plan9.386: GOARCH=386 +plan9.amd64: GOARCH=amd64 +solaris.amd64: GOARCH=amd64 +windows.386: GOARCH=386 +windows.amd64: GOARCH=amd64 + +all: test build archive +test: main.go + go test + +build: darwin.386 darwin.amd64 darwin.arm dragonfly.amd64 freebsd.386 freebsd.amd64 freebsd.arm linux.386 linux.amd64 linux.arm linux.arm64 linux.ppc64 linux.ppc64le linux.mips64 linux.mips64le +# https://golang.org/doc/install/source#environment +# android.arm +# darwin.arm64 +# linux.mips +# linux.mipsle + +clean: + go clean + @rm -rvf $(BUILDDIR) + @rm -rvf $(ARCHIVEDIR) + +archive: + @mkdir -p $(ARCHIVEDIR) + @for dir in $$(ls $(BUILDDIR)); do \ + echo tar -czf $(ARCHIVEDIR)/$$dir.tgz; \ + tar -czf $(ARCHIVEDIR)/$$dir.tgz -C $(BUILDDIR)/$$dir $(TARGET) ; \ + done + +android.arm: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +darwin.386: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +darwin.amd64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +darwin.arm: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +darwin.arm64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +dragonfly.amd64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +freebsd.386: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +freebsd.amd64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +freebsd.arm: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.386: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.amd64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.arm: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.arm64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.ppc64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.ppc64le: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.mips: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.mipsle: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.mips64: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) +linux.mips64le: + @mkdir -p $(BUILDDIR)/$(GOOS)_$(GOARCH) + GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BUILDDIR)/$(GOOS)_$(GOARCH)/$(TARGET) + +.PHONY: archive clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..3451566 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# selenium-check + +This tool is designed to test selenium installations, written for [selenium ansible role](/Guidewire/ansible-role-selenium). It connects to selenium, navigates to `/grid/console`, gets `h2` header and prints it. + +Currently requires `chrome` on `linux`. + +Use `-h` flag to specify selenium host, `-s` for a screenshot file name, screenshot is made only when flag is defined. + +#### Example + +``` +$ selenium-check -h 172.28.128.14 -s test2 +2017/03/31 11:38:11 Connecting to selenium +2017/03/31 11:38:12 Navigating to URL +2017/03/31 11:38:12 Getting header +2017/03/31 11:38:12 Getting test2.jpg screenshot +Grid Console v.3.3.1 +``` diff --git a/main.go b/main.go new file mode 100644 index 0000000..f3ad2c8 --- /dev/null +++ b/main.go @@ -0,0 +1,81 @@ +package main + +import ( + "flag" + "fmt" + "github.com/sclevine/agouti" + "log" + "regexp" +) + +const defaultSeleniumPort = 4444 +const defaultSeleniumProto = "http" +const defaultSeleniumAddr = "127.0.0.1" + +var selenium_url = flag.String("h", fmt.Sprintf("%s://%s:%d", defaultSeleniumProto, defaultSeleniumAddr, defaultSeleniumPort), "Selenium host URL. Http is used if no protocol is specified") +var screenshot_file = flag.String("s", "", "Take final screenshot and save it to file with this name") + +func checkErrFatal(err error) { + if err != nil { + log.Panic(err) + } +} + +func getSeleniumURL(url string) string { + return getValidUrl(url) + "/wd/hub" +} + +func getValidUrl(url string) string { + matched, err := regexp.MatchString("^https?://", url) + checkErrFatal(err) + if !matched { + url = defaultSeleniumProto + "://" + url + } + matched, err = regexp.MatchString(`.*:\d+`, url) + checkErrFatal(err) + if !matched { + url = fmt.Sprintf("%s:%d", url, defaultSeleniumPort) + } + return url +} + +func getValidScreenshotFile(name string) string { + matched, err := regexp.MatchString(`.*\.jpe?g$`, name) + checkErrFatal(err) + if !matched { + name = name + ".jpg" + } + return name +} + +func main() { + flag.Parse() + seleniumURL := getValidUrl(*selenium_url) + capabilities := agouti.NewCapabilities().Browser("chrome").Platform("linux").With("javascriptEnabled") + log.Println("Connecting to selenium") + page, err := agouti.NewPage(seleniumURL+"/wd/hub", agouti.Desired(capabilities)) + if err != nil { + log.Fatal("Failed to open page:", err) + } + + log.Println("Navigating to URL") + if err := page.Navigate(seleniumURL + "/grid/console"); err != nil { + log.Fatal("Failed to navigate:", err) + } + + log.Println("Getting header") + selection, err := page.FindByID("header").All("h2").Text() + if err != nil { + log.Fatal("Failed to get element:", err) + } + + if *screenshot_file != "" { + screenshotFile := getValidScreenshotFile(*screenshot_file) + log.Printf("Getting %s screenshot\n", screenshotFile) + err = page.Screenshot(screenshotFile) + if err != nil { + log.Fatal("Failed to get screenshot:", err) + } + } + fmt.Println(selection) +} diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..7c02fae --- /dev/null +++ b/main_test.go @@ -0,0 +1,41 @@ +package main + +import "testing" + +func TestGetValidUrl(t *testing.T) { + cases := map[string]struct{ addr_string, expected string }{ + "full address string": {"http://127.0.0.1:4444", "http://127.0.0.1:4444"}, + "no port": {"http://127.0.0.1", "http://127.0.0.1:4444"}, + "no proto": {"127.0.0.1:4444", "http://127.0.0.1:4444"}, + } + + for k, tc := range cases { + actual := getValidUrl(tc.addr_string) + if actual != tc.expected { + t.Errorf( + "%s: URL is '%s', expected '%s'", + k, tc.addr_string, tc.expected, + ) + } + } + +} + +func TestGetValidScreenshotFile(t *testing.T) { + cases := map[string]struct{ name, expected string }{ + "no extension": {"screenshot", "screenshot.jpg"}, + "jpeg extension": {"screenshot.jpeg", "screenshot.jpeg"}, + "jpg extension": {"screenshot.jpg", "screenshot.jpg"}, + } + + for k, tc := range cases { + actual := getValidScreenshotFile(tc.name) + if actual != tc.expected { + t.Errorf( + "%s: URL is '%s', expected '%s'", + k, tc.name, tc.expected, + ) + } + } + +}