Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 163 additions & 1 deletion apps/headless/Tests/macos-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set -euo pipefail
cd "${0:a:h}/.."

for tool in node curl defaults lsof osascript perl; do
for tool in node curl defaults lsof osascript perl swift; do
command -v "$tool" >/dev/null 2>&1 || { echo "macOS E2E tests require $tool" >&2; exit 69; }
done

Expand Down Expand Up @@ -197,6 +197,75 @@ end run
APPLESCRIPT
}

ax_address_field_count() {
local pid="$1"
osascript_with_timeout - "$pid" <<'APPLESCRIPT'
on run argv
set targetPID to item 1 of argv as integer
tell application "System Events"
set targetProcesses to every application process whose unix id is targetPID
if (count of targetProcesses) is not 1 then error "Headless accessibility process was not found"
tell item 1 of targetProcesses
if (count of windows) is 0 then error "Headless has no accessible windows"
return count of text fields of front window
end tell
end tell
end run
APPLESCRIPT
}

ax_click_front_window_content() {
local pid="$1"
local coordinates x y
coordinates="$(osascript_with_timeout - "$pid" <<'APPLESCRIPT'
on run argv
set targetPID to item 1 of argv as integer
tell application "System Events"
set targetProcesses to every application process whose unix id is targetPID
if (count of targetProcesses) is not 1 then error "Headless accessibility process was not found"
tell item 1 of targetProcesses
set frontmost to true
if (count of windows) is 0 then error "Headless has no accessible windows"
set windowPosition to position of front window
set windowSize to size of front window
return {(item 1 of windowPosition) + 10, (item 2 of windowPosition) + (item 2 of windowSize) - 10}
end tell
end tell
end run
APPLESCRIPT
)"
x="$(printf '%s' "$coordinates" | cut -d, -f1 | tr -d ' ')"
y="$(printf '%s' "$coordinates" | cut -d, -f2 | tr -d ' ')"
swift - "$x" "$y" <<'SWIFT'
import CoreGraphics
import Foundation

guard CommandLine.arguments.count == 3,
let x = Double(CommandLine.arguments[1]),
let y = Double(CommandLine.arguments[2]) else {
fputs("invalid click coordinates\n", stderr)
exit(64)
}
let point = CGPoint(
x: x,
y: y
)
CGEvent(
mouseEventSource: nil,
mouseType: .leftMouseDown,
mouseCursorPosition: point,
mouseButton: .left
)?.post(tap: .cghidEventTap)
usleep(50_000)
CGEvent(
mouseEventSource: nil,
mouseType: .leftMouseUp,
mouseCursorPosition: point,
mouseButton: .left
)?.post(tap: .cghidEventTap)
SWIFT
}

ax_named_window_count() {
local pid="$1" window_title="$2"
osascript_with_timeout - "$pid" "$window_title" <<'APPLESCRIPT'
Expand Down Expand Up @@ -735,6 +804,99 @@ if [[ "$(frontmost_pid)" == "$HOST_PID" ]]; then
fail
fi

STEP="start-page-themes"
for _ in {1..100}; do
NORMAL_START_PAGE="$("$CLI" inspect --text 2>/dev/null || true)"
echo "$NORMAL_START_PAGE" | grep -q "QUICK CONTROLS" && break
sleep 0.05
done
echo "$NORMAL_START_PAGE" | grep -q "QUICK CONTROLS"
if echo "$NORMAL_START_PAGE" | grep -q "the browser that isn"; then
echo "normal start page retained the removed tagline" >&2
fail
fi
if echo "$NORMAL_START_PAGE" | grep -q "PRIVATE SESSION"; then
echo "normal start page was marked private" >&2
fail
fi
"$CLI" session create start-page-private --isolated | grep -q '"isolated":true'
for _ in {1..100}; do
PRIVATE_START_PAGE="$("$CLI" --session start-page-private inspect --text 2>/dev/null || true)"
echo "$PRIVATE_START_PAGE" | grep -q "PRIVATE SESSION" && break
sleep 0.05
done
echo "$PRIVATE_START_PAGE" | grep -q "Private browsing data is erased when this session closes."
if echo "$PRIVATE_START_PAGE" | grep -q "the browser that isn"; then
echo "private start page inherited the normal tagline" >&2
fail
fi
"$CLI" session close start-page-private | grep -q '"closed":"start-page-private"'

STEP="start-page-address-hud"
ax_press_menu_item "$HOST_PID" File "Open Location…"
for _ in {1..100}; do
[[ "$(ax_address_field_count "$HOST_PID" 2>/dev/null)" == 1 ]] && break
sleep 0.05
done
if [[ "$(ax_address_field_count "$HOST_PID")" != 1 ]]; then
echo "start page address field did not open" >&2
fail
fi
ax_click_front_window_content "$HOST_PID"
sleep 0.2
if [[ "$(ax_address_field_count "$HOST_PID")" != 1 ]]; then
echo "start page click dismissed the address field" >&2
fail
fi
ax_keystroke "$HOST_PID" l command
ax_escape "$HOST_PID"
for _ in {1..100}; do
[[ "$(ax_address_field_count "$HOST_PID" 2>/dev/null)" == 0 ]] && break
sleep 0.05
done
if [[ "$(ax_address_field_count "$HOST_PID")" != 0 ]]; then
echo "Escape did not dismiss the focused start page address field" >&2
fail
fi

STEP="website-address-hud"
"$CLI" visit "http://127.0.0.1:$PORT/designers/dashboard" | grep -q 'Designers Dashboard'
ax_press_menu_item "$HOST_PID" File "Open Location…"
for _ in {1..100}; do
[[ "$(ax_address_field_count "$HOST_PID" 2>/dev/null)" == 1 ]] && break
sleep 0.05
done
if [[ "$(ax_address_field_count "$HOST_PID")" != 1 ]]; then
echo "website address field did not open" >&2
fail
fi
ax_escape "$HOST_PID"
ax_press_menu_item "$HOST_PID" File "Open Location…"
for _ in {1..100}; do
[[ "$(ax_address_field_count "$HOST_PID" 2>/dev/null)" == 1 ]] && break
sleep 0.05
done
if [[ "$(ax_address_field_count "$HOST_PID")" != 1 ]]; then
echo "website address field did not reopen after dismissal" >&2
fail
fi
ax_click_front_window_content "$HOST_PID"
for _ in {1..100}; do
[[ "$(ax_address_field_count "$HOST_PID" 2>/dev/null)" == 0 ]] && break
sleep 0.05
done
if [[ "$(ax_address_field_count "$HOST_PID")" != 0 ]]; then
echo "website click did not dismiss the address field" >&2
fail
fi
ax_escape "$HOST_PID"
for _ in {1..100}; do
NORMAL_START_PAGE="$("$CLI" inspect --text 2>/dev/null || true)"
echo "$NORMAL_START_PAGE" | grep -q "QUICK CONTROLS" && break
sleep 0.05
done
echo "$NORMAL_START_PAGE" | grep -q "QUICK CONTROLS"

STEP="settings-window-workflow"
ax_press_menu_item "$HOST_PID" Headless "Settings…"
for _ in {1..100}; do
Expand Down
2 changes: 1 addition & 1 deletion apps/headless/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fi
export CLANG_MODULE_CACHE_PATH="$PWD/build/module-cache"
export SWIFTPM_MODULECACHE_OVERRIDE="$PWD/build/swiftpm-module-cache"

if [[ ! -f "$ICON" ]]; then
if [[ ! -f "$ICON" || tools/make-icon.swift -nt "$ICON" ]]; then
echo "▸ rendering icon"
rm -rf build/AppIcon.iconset
mkdir -p build
Expand Down
Loading