Files
magpie/internal/gui/appkit_darwin_test.go
forever 89b3a20f5d gui tests: a test run leaves no gui.test folder in the real ~/Library/WebKit or ~/Library/Caches (waitingsnow) (#1047)
TestTrayCellClickReleasedPanel shows its panel in the test binary run
again as a child. The package's TestMain gives the tests testenv's HOME,
but WebKit takes the home from the account's record, so every run wrote
the child's WebKit data to ~/Library/WebKit/gui.test and its caches to
~/Library/Caches/gui.test in the real home.

The child now starts through runAppKit (appkit_darwin_test.go). It sets
CFFIXED_USER_HOME, which CoreFoundation reads before the account's
record, to a temporary folder, so WebKit's data and caches go there. It
runs the binary under a name of its own, through a hard link: WebKit
names its folders after the process, whose name comes from the file, not
argv[0]. The test fails when a folder of that name is left in the real
~/Library/WebKit or ~/Library/Caches. The empty folders WebKit makes
under the name in the account's temporary folder (NSTemporaryDirectory,
which TMPDIR doesn't move) are removed. Wails v3 beta.24 offers no
non-persistent WKWebsiteDataStore: its windowNew makes a plain
WKWebViewConfiguration, which uses WebKit's default store.

CFFIXED_USER_HOME doesn't move the account's settings: cfprefsd still
serves the global domain and com.apple.universalaccess, where dark mode
and Increase Contrast are kept. A probe window read the same appearance,
Increase Contrast, Reduce Transparency, layout direction, languages and
non-default values (AppleShowScrollBars, AppleReduceDesktopTinting, the
zoom factor) with and without it, on macOS 26.7.1. Nothing is written
to the temporary home after the child exits.

Without CFFIXED_USER_HOME the test fails:

    trayusage_panel_darwin_test.go:20: the windows' process left /Users/wei/Library/WebKit/gui.test-1791307161567260000 in the account's real home
    trayusage_panel_darwin_test.go:20: the windows' process left /Users/wei/Library/Caches/gui.test-1791307161567260000 in the account's real home
    --- FAIL: TestTrayCellClickReleasedPanel (0.45s)

With it, it passes, and nothing new appears in the real ~/Library or in
the temporary folder.

PR #1042's TestMainWindowCorners and TestMainWindowRightToLeft, moved
onto runAppKit at its head f89991b1, pass and print the same with and
without CFFIXED_USER_HOME: corners 16.00pt (plain 16.00, toolbar
26.00), lights [[26 26] [49 26] [72 26]], title bar 66pt, a sheet 66pt
below the top, right to left lights [[874 26] [851 26] [828 26]].
Without it, both fail the same way.

go vet ./..., go build ./..., GOOS=linux go build -tags nogui ./...,
GOOS=windows go build ./..., go test -tags nogui ./..., go test
-count=1 ./internal/gui/... and gofmt -l pass under a temp HOME with
Go's caches pinned. docs/subsystems/gui-shell.md says it. Tests only.
2026-10-07 02:23:19 +08:00

66 lines
2.1 KiB
Go

//go:build darwin && cgo && !nogui
package gui
import (
"context"
"errors"
"fmt"
"io/fs"
"os"
"os/exec"
"os/user"
"path/filepath"
"testing"
"time"
)
// runAppKit runs this test binary again under a name of its own, as AppKit
// needs a process's main thread, with env and args added, and gives what it
// printed. WebKit keeps data in folders named after the process under the
// account's home, not HOME, so CFFIXED_USER_HOME gives it a temporary home,
// and the test fails when such a folder is left in the real ~/Library.
func runAppKit(t *testing.T, timeout time.Duration, env []string, args ...string) ([]byte, error) {
t.Helper()
self, err := os.Executable()
if err != nil {
t.Fatal(err)
}
name := fmt.Sprintf("%s-%d", filepath.Base(self), time.Now().UnixNano())
bin := filepath.Join(t.TempDir(), name)
if err := os.Link(self, bin); err != nil {
b, err := os.ReadFile(self)
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(bin, b, 0o755); err != nil {
t.Fatal(err)
}
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, bin, args...)
cmd.Env = append(append(os.Environ(), env...), "XDG_CONFIG_HOME="+t.TempDir(), "CFFIXED_USER_HOME="+t.TempDir())
out, err := cmd.CombinedOutput()
// WebKit also makes empty folders under the name in the account's
// temporary folder, which TMPDIR doesn't move; the name is this run's.
if rerr := os.RemoveAll(filepath.Join(os.TempDir(), name)); rerr != nil {
t.Errorf("can't remove WebKit's temporary folders: %v", rerr)
}
account, uerr := user.Current()
if uerr != nil {
t.Errorf("can't tell where the account's home is: %v", uerr)
return out, err
}
for _, dir := range []string{"WebKit", "Caches"} {
left := filepath.Join(account.HomeDir, "Library", dir, name)
switch _, serr := os.Lstat(left); {
case serr == nil:
t.Errorf("the windows' process left %s in the account's real home", left)
case !errors.Is(serr, fs.ErrNotExist):
t.Errorf("can't tell whether the windows' process left %s: %v", left, serr)
}
}
return out, err
}