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.
66 lines
2.1 KiB
Go
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
|
|
}
|