mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 23:55:39 +00:00
97d13922dd
We can instead synchronize with the gio app via stdout. We need three states, since we need to first invalidate a frame and then print when the next frame is drawn. This is not happening on the JS test yet, because stdout printing crashes in that case. See the comment. This change should make the X11 test a bit faster on fast machines, while making it more stable in small or headless machines like CI. Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
118 lines
3.7 KiB
Go
118 lines
3.7 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
package main_test
|
|
|
|
import (
|
|
"flag"
|
|
"image"
|
|
"image/color"
|
|
"testing"
|
|
)
|
|
|
|
var headless = flag.Bool("headless", true, "run end-to-end tests in headless mode")
|
|
|
|
// TestDriver is implemented by each of the platforms we can run end-to-end
|
|
// tests on. None of its methods return any errors, as the errors are directly
|
|
// reported to testing.T via methods like Fatal.
|
|
type TestDriver interface {
|
|
// Start provides the test driver with a testing.T, as well as the path
|
|
// to the Gio app to use for the test. The app will be run with the
|
|
// given width and height, and the platform's background should be
|
|
// white.
|
|
//
|
|
// When the function returns, the gio app must be ready to use on the
|
|
// platform, with its initial frame fully drawn.
|
|
//
|
|
// The returned cleanup funcs must be run in reverse order, to mimic
|
|
// deferred funcs.
|
|
// TODO(mvdan): replace with testing.T.Cleanup once Go 1.14 is out.
|
|
Start(t *testing.T, path string, width, height int) (cleanups []func())
|
|
|
|
// Screenshot takes a screenshot of the Gio app on the platform.
|
|
Screenshot() image.Image
|
|
|
|
// Click performs a pointer click at the specified coordinates,
|
|
// including both press and release. It returns when the next frame is
|
|
// fully drawn.
|
|
Click(x, y int)
|
|
}
|
|
|
|
func runEndToEndTest(t *testing.T, driver TestDriver) {
|
|
width, height := 800, 600
|
|
cleanups := driver.Start(t, "testdata/red.go", width, height)
|
|
for _, cleanup := range cleanups {
|
|
defer cleanup()
|
|
}
|
|
|
|
// The colors are split in four rectangular sections. Check the corners
|
|
// of each of the sections. We check the corners left to right, top to
|
|
// bottom, like when reading left-to-right text.
|
|
wantColors := func(topLeft, topRight, botLeft, botRight color.RGBA) {
|
|
t.Helper()
|
|
img := driver.Screenshot()
|
|
size := img.Bounds().Size()
|
|
// We expect to receive a width*height screenshot.
|
|
if size.X != width || size.Y != height {
|
|
t.Fatalf("expected dimensions to be %d*%d, got %d*%d",
|
|
width, height, size.X, size.Y)
|
|
}
|
|
{
|
|
minX, minY := 5, 5
|
|
maxX, maxY := (width/2)-5, (height/2)-5
|
|
wantColor(t, img, minX, minY, topLeft)
|
|
wantColor(t, img, maxX, minY, topLeft)
|
|
wantColor(t, img, minX, maxY, topLeft)
|
|
wantColor(t, img, maxX, maxY, topLeft)
|
|
}
|
|
{
|
|
minX, minY := (width/2)+5, 5
|
|
maxX, maxY := width-5, (height/2)-5
|
|
wantColor(t, img, minX, minY, topRight)
|
|
wantColor(t, img, maxX, minY, topRight)
|
|
wantColor(t, img, minX, maxY, topRight)
|
|
wantColor(t, img, maxX, maxY, topRight)
|
|
}
|
|
{
|
|
minX, minY := 5, (height/2)+5
|
|
maxX, maxY := (width/2)-5, height-5
|
|
wantColor(t, img, minX, minY, botLeft)
|
|
wantColor(t, img, maxX, minY, botLeft)
|
|
wantColor(t, img, minX, maxY, botLeft)
|
|
wantColor(t, img, maxX, maxY, botLeft)
|
|
}
|
|
{
|
|
minX, minY := (width/2)+5, (height/2)+5
|
|
maxX, maxY := width-5, height-5
|
|
wantColor(t, img, minX, minY, botRight)
|
|
wantColor(t, img, maxX, minY, botRight)
|
|
wantColor(t, img, minX, maxY, botRight)
|
|
wantColor(t, img, maxX, maxY, botRight)
|
|
}
|
|
}
|
|
|
|
beef := color.RGBA{R: 0xde, G: 0xad, B: 0xbe}
|
|
white := color.RGBA{R: 0xff, G: 0xff, B: 0xff}
|
|
black := color.RGBA{R: 0x00, G: 0x00, B: 0x00}
|
|
gray := color.RGBA{R: 0xbb, G: 0xbb, B: 0xbb}
|
|
red := color.RGBA{R: 0xff, G: 0x00, B: 0x00}
|
|
|
|
// These are the four colors at the beginning.
|
|
wantColors(beef, white, black, gray)
|
|
|
|
// Click the first and last sections to turn them red.
|
|
driver.Click(1*(width/4), 1*(height/4))
|
|
driver.Click(3*(width/4), 3*(height/4))
|
|
wantColors(red, white, black, red)
|
|
}
|
|
|
|
func wantColor(t *testing.T, img image.Image, x, y int, want color.Color) {
|
|
t.Helper()
|
|
r, g, b, _ := want.RGBA()
|
|
got := img.At(x, y)
|
|
r_, g_, b_, _ := got.RGBA()
|
|
if r_ != r || g_ != g || b_ != b {
|
|
t.Errorf("got 0x%04x%04x%04x at (%d,%d), want 0x%04x%04x%04x",
|
|
r_, g_, b_, x, y, r, g, b)
|
|
}
|
|
}
|