2018-04-06 15:16:15 +00:00
|
|
|
package test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
2018-07-11 09:00:06 +00:00
|
|
|
"time"
|
2018-04-06 15:16:15 +00:00
|
|
|
"unicode/utf8"
|
|
|
|
|
|
|
|
"github.com/gdamore/tcell"
|
|
|
|
"github.com/gdamore/tcell/terminfo"
|
2018-04-07 04:55:05 +00:00
|
|
|
ginkgo "github.com/onsi/ginkgo"
|
2018-04-06 15:16:15 +00:00
|
|
|
gomega "github.com/onsi/gomega"
|
|
|
|
|
|
|
|
"browsh/interfacer/src/browsh"
|
|
|
|
)
|
|
|
|
|
2018-05-27 12:31:47 +00:00
|
|
|
var staticFileServerPort = "4444"
|
2018-04-06 15:16:15 +00:00
|
|
|
var simScreen tcell.SimulationScreen
|
2018-06-10 13:01:49 +00:00
|
|
|
var startupWait = 60 * time.Second
|
2018-04-06 15:16:15 +00:00
|
|
|
var perTestTimeout = 2000 * time.Millisecond
|
|
|
|
var rootDir = browsh.Shell("git rev-parse --show-toplevel")
|
2018-05-27 12:31:47 +00:00
|
|
|
var testSiteURL = "http://localhost:" + staticFileServerPort
|
2018-04-06 15:16:15 +00:00
|
|
|
var ti *terminfo.Terminfo
|
|
|
|
|
|
|
|
func initTerm() {
|
|
|
|
// The tests check for true colour RGB values. The only downside to forcing true colour
|
|
|
|
// in tests is that snapshots of frames with true colour ANSI codes are output to logs.
|
|
|
|
// Some people may not have true colour terminals, for example like on Travis, so cat'ing
|
|
|
|
// logs may appear corrupt.
|
|
|
|
ti, _ = terminfo.LookupTerminfo("xterm-truecolor")
|
|
|
|
}
|
|
|
|
|
2018-05-27 12:31:47 +00:00
|
|
|
// GetFrame returns the current Browsh frame's text
|
2018-04-06 15:16:15 +00:00
|
|
|
func GetFrame() string {
|
|
|
|
var frame, log string
|
|
|
|
var line = 0
|
|
|
|
var styleDefault = ti.TParm(ti.SetFgBg, int(tcell.ColorWhite), int(tcell.ColorBlack))
|
|
|
|
width, _ := simScreen.Size()
|
|
|
|
cells, _, _ := simScreen.GetContents()
|
|
|
|
for _, element := range cells {
|
|
|
|
line++
|
|
|
|
frame += string(element.Runes)
|
|
|
|
log += elementColourForTTY(element) + string(element.Runes)
|
|
|
|
if line == width {
|
|
|
|
frame += "\n"
|
|
|
|
log += styleDefault + "\n"
|
|
|
|
line = 0
|
|
|
|
}
|
|
|
|
}
|
2018-04-07 04:55:05 +00:00
|
|
|
log = "\n" + log + styleDefault
|
|
|
|
ginkgo.GinkgoWriter.Write([]byte(log))
|
2018-04-06 15:16:15 +00:00
|
|
|
return frame
|
|
|
|
}
|
|
|
|
|
|
|
|
// SpecialKey injects a special key into the TTY. See Tcell's `keys.go` file for all
|
|
|
|
// the available special keys.
|
|
|
|
func SpecialKey(key tcell.Key) {
|
|
|
|
simScreen.InjectKey(key, 0, tcell.ModNone)
|
2018-05-20 13:17:33 +00:00
|
|
|
time.Sleep(100 * time.Millisecond)
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Keyboard types a string of keys into the TTY, as if a user would
|
|
|
|
func Keyboard(keys string) {
|
|
|
|
for _, char := range keys {
|
|
|
|
simScreen.InjectKey(tcell.KeyRune, char, tcell.ModNone)
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func waitForNextFrame() {
|
|
|
|
// Need to wait so long because the frame rate is currently so slow
|
|
|
|
// TODO: Reduce the wait when the FPS is higher
|
2018-05-08 06:07:54 +00:00
|
|
|
time.Sleep(250 * time.Millisecond)
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
|
2018-04-07 04:55:05 +00:00
|
|
|
// WaitForText waits for a particular string at particular position in the frame
|
|
|
|
func WaitForText(text string, x, y int) {
|
|
|
|
var found string
|
|
|
|
start := time.Now()
|
|
|
|
for time.Since(start) < perTestTimeout {
|
|
|
|
found = GetText(x, y, runeCount(text))
|
2018-07-11 09:00:06 +00:00
|
|
|
if found == text {
|
|
|
|
return
|
|
|
|
}
|
2018-04-07 04:55:05 +00:00
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
}
|
|
|
|
panic("Waiting for '" + text + "' to appear but it didn't")
|
|
|
|
}
|
|
|
|
|
2018-04-18 13:11:04 +00:00
|
|
|
// WaitForPageLoad waits for the page to load
|
|
|
|
func WaitForPageLoad() {
|
2018-05-24 10:45:07 +00:00
|
|
|
sleepUntilPageLoad(perTestTimeout)
|
|
|
|
}
|
|
|
|
|
|
|
|
func sleepUntilPageLoad(maxTime time.Duration) {
|
2018-04-18 13:11:04 +00:00
|
|
|
start := time.Now()
|
2018-05-24 10:45:07 +00:00
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
for time.Since(start) < maxTime {
|
|
|
|
if browsh.CurrentTab != nil {
|
|
|
|
if browsh.CurrentTab.PageState == "parsing_complete" {
|
2018-06-04 09:02:15 +00:00
|
|
|
time.Sleep(200 * time.Millisecond)
|
2018-05-24 10:45:07 +00:00
|
|
|
return
|
|
|
|
}
|
2018-04-18 13:11:04 +00:00
|
|
|
}
|
2018-05-20 13:17:33 +00:00
|
|
|
time.Sleep(50 * time.Millisecond)
|
2018-04-18 13:11:04 +00:00
|
|
|
}
|
|
|
|
panic("Page didn't load within timeout")
|
|
|
|
}
|
|
|
|
|
2018-04-06 15:16:15 +00:00
|
|
|
// GotoURL sends the browsh browser to the specified URL
|
|
|
|
func GotoURL(url string) {
|
|
|
|
SpecialKey(tcell.KeyCtrlL)
|
|
|
|
Keyboard(url)
|
|
|
|
SpecialKey(tcell.KeyEnter)
|
2018-04-18 13:11:04 +00:00
|
|
|
WaitForPageLoad()
|
2018-04-07 04:55:05 +00:00
|
|
|
// TODO: Looking for the URL isn't optimal because it could be the same URL
|
|
|
|
// as the previous test.
|
2018-05-24 10:45:07 +00:00
|
|
|
gomega.Expect(url).To(BeInFrameAt(0, 1))
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
|
2018-05-27 12:31:47 +00:00
|
|
|
func mouseClick(x, y int) {
|
|
|
|
simScreen.InjectMouse(x, y, 1, tcell.ModNone)
|
|
|
|
simScreen.InjectMouse(x, y, 0, tcell.ModNone)
|
|
|
|
}
|
|
|
|
|
2018-04-06 15:16:15 +00:00
|
|
|
func elementColourForTTY(element tcell.SimCell) string {
|
|
|
|
var fg, bg tcell.Color
|
|
|
|
fg, bg, _ = element.Style.Decompose()
|
|
|
|
r1, g1, b1 := fg.RGB()
|
|
|
|
r2, g2, b2 := bg.RGB()
|
|
|
|
return ti.TParm(ti.SetFgBgRGB,
|
2018-07-11 09:00:06 +00:00
|
|
|
int(r1), int(g1), int(b1),
|
|
|
|
int(r2), int(g2), int(b2))
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetText retruns an individual piece of a frame
|
|
|
|
func GetText(x, y, length int) string {
|
|
|
|
var text string
|
|
|
|
frame := []rune(GetFrame())
|
|
|
|
width, _ := simScreen.Size()
|
|
|
|
index := ((width + 1) * y) + x
|
|
|
|
for {
|
|
|
|
text += string(frame[index])
|
|
|
|
index++
|
2018-07-11 09:00:06 +00:00
|
|
|
if runeCount(text) == length {
|
|
|
|
break
|
|
|
|
}
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
return text
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetFgColour returns the foreground colour of a single cell
|
|
|
|
func GetFgColour(x, y int) [3]int32 {
|
|
|
|
GetFrame()
|
|
|
|
cells, _, _ := simScreen.GetContents()
|
|
|
|
width, _ := simScreen.Size()
|
|
|
|
index := (width * y) + x
|
|
|
|
fg, _, _ := cells[index].Style.Decompose()
|
|
|
|
r1, g1, b1 := fg.RGB()
|
|
|
|
return [3]int32{r1, g1, b1}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBgColour returns the background colour of a single cell
|
|
|
|
func GetBgColour(x, y int) [3]int32 {
|
|
|
|
GetFrame()
|
|
|
|
cells, _, _ := simScreen.GetContents()
|
|
|
|
width, _ := simScreen.Size()
|
|
|
|
index := (width * y) + x
|
|
|
|
_, bg, _ := cells[index].Style.Decompose()
|
|
|
|
r1, g1, b1 := bg.RGB()
|
|
|
|
return [3]int32{r1, g1, b1}
|
|
|
|
}
|
|
|
|
|
2018-05-25 07:08:25 +00:00
|
|
|
func ensureOnlyOneTab() {
|
2018-07-11 09:00:06 +00:00
|
|
|
if len(browsh.Tabs) > 1 {
|
2018-05-25 07:08:25 +00:00
|
|
|
SpecialKey(tcell.KeyCtrlW)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-27 12:31:47 +00:00
|
|
|
func startStaticFileServer() {
|
2018-04-06 15:16:15 +00:00
|
|
|
serverMux := http.NewServeMux()
|
2018-07-11 09:00:06 +00:00
|
|
|
serverMux.Handle("/", http.FileServer(http.Dir(rootDir+"/interfacer/test/sites")))
|
|
|
|
http.ListenAndServe(":"+staticFileServerPort, serverMux)
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func startBrowsh() {
|
2018-05-27 12:31:47 +00:00
|
|
|
browsh.IsTesting = true
|
2018-04-06 15:16:15 +00:00
|
|
|
simScreen = tcell.NewSimulationScreen("UTF-8")
|
2018-05-27 12:31:47 +00:00
|
|
|
browsh.TTYStart(simScreen)
|
2018-04-06 15:16:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func runeCount(text string) int {
|
|
|
|
return utf8.RuneCountInString(text)
|
|
|
|
}
|
|
|
|
|
2018-07-11 09:00:06 +00:00
|
|
|
var _ = ginkgo.BeforeEach(func() {
|
2018-04-28 11:02:40 +00:00
|
|
|
browsh.IsMonochromeMode = false
|
2018-04-07 04:55:05 +00:00
|
|
|
browsh.Log("\n---------")
|
|
|
|
browsh.Log(ginkgo.CurrentGinkgoTestDescription().FullTestText)
|
|
|
|
browsh.Log("---------")
|
|
|
|
})
|
|
|
|
|
|
|
|
var _ = ginkgo.BeforeSuite(func() {
|
2018-04-06 15:16:15 +00:00
|
|
|
initTerm()
|
2018-05-27 12:31:47 +00:00
|
|
|
go startStaticFileServer()
|
2018-04-06 15:16:15 +00:00
|
|
|
go startBrowsh()
|
2018-05-24 10:45:07 +00:00
|
|
|
sleepUntilPageLoad(startupWait)
|
2018-04-06 15:16:15 +00:00
|
|
|
})
|
|
|
|
|
2018-07-11 09:00:06 +00:00
|
|
|
var _ = ginkgo.AfterSuite(func() {
|
2018-04-06 15:16:15 +00:00
|
|
|
browsh.Shell(rootDir + "/webext/contrib/firefoxheadless.sh kill")
|
|
|
|
})
|