Skip to content

Commit bc512af

Browse files
committed
chore(desktop): validate rebased consent polish in isolation
1 parent d4f8483 commit bc512af

8 files changed

Lines changed: 45 additions & 237 deletions

File tree

‎.github/workflows/desktop-e2e.yml‎

Lines changed: 20 additions & 225 deletions
Original file line numberDiff line numberDiff line change
@@ -1,239 +1,34 @@
1-
name: desktop-e2e
2-
3-
# Smoke coverage of the real Electron shell on desktop changes, plus a weekly
4-
# advisory canary against electron@latest so Chromium-cadence breakage surfaces
5-
# before an upgrade is attempted.
6-
1+
name: desktop-consent-full-validation
72
on:
8-
pull_request:
9-
paths:
10-
- '.github/workflows/desktop-e2e.yml'
11-
- '.github/workflows/desktop-release.yml'
12-
- 'apps/desktop/**'
13-
- 'apps/sim/app/_shell/desktop-update-*.tsx'
14-
- 'apps/sim/app/workspace/**/home/hooks/use-mothership-resize.ts'
15-
- 'apps/sim/app/workspace/**/home/hooks/use-resource-panel.ts'
16-
- 'apps/sim/app/workspace/**/home/components/chat-panel-layout.tsx'
17-
- 'apps/sim/stores/chat-panel/**'
18-
- 'apps/sim/stores/constants.ts'
19-
- 'apps/sim/lib/browser-agent/transport.ts'
20-
- 'apps/sim/lib/core/utils/separator-keys.ts'
21-
- 'apps/sim/scripts/fixtures/chat-panel.tsx'
22-
- 'apps/sim/app/layout.tsx'
23-
- 'apps/sim/hooks/use-desktop-update-state.ts'
24-
- 'apps/sim/lib/desktop/**'
25-
- 'apps/sim/app/desktop/connect/**'
26-
- 'apps/sim/app/credential-groups/**'
27-
- 'apps/sim/hooks/queries/slack-search.ts'
28-
- 'apps/sim/hooks/queries/personal-search-integrations.ts'
29-
- 'apps/sim/hooks/use-search-integration-connection.ts'
30-
- 'apps/sim/hooks/use-github-installation-setup.ts'
31-
- 'apps/sim/lib/api/contracts/desktop-source-connect.ts'
32-
- 'apps/sim/scripts/fixtures/desktop-source-connect.tsx'
33-
- 'apps/sim/app/workspace/**/browser-session/**'
34-
- 'apps/sim/app/_styles/**'
35-
- 'apps/sim/lib/postcss/**'
36-
- 'apps/sim/postcss.config.mjs'
37-
- 'apps/sim/public/brand/fonts/**'
38-
- 'packages/emcn/**'
39-
- 'packages/desktop-bridge/**'
40-
- 'packages/browser-protocol/**'
41-
- 'packages/terminal-protocol/**'
42-
- 'packages/logger/**'
43-
- 'packages/security/**'
44-
- 'packages/tsconfig/**'
45-
- 'packages/utils/**'
46-
- 'bun.lock'
47-
- 'package.json'
48-
schedule:
49-
- cron: '23 9 * * 1'
503
workflow_dispatch:
51-
524
permissions:
535
contents: read
54-
55-
concurrency:
56-
group: desktop-e2e-${{ github.ref }}
57-
cancel-in-progress: true
58-
596
jobs:
60-
e2e:
61-
name: e2e
62-
if: github.event_name != 'schedule'
63-
runs-on: macos-26
64-
timeout-minutes: 30
7+
gate:
8+
runs-on: ubuntu-latest
9+
timeout-minutes: 40
6510
steps:
66-
- name: Checkout code
67-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
11+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
6812
with:
6913
persist-credentials: false
70-
71-
- name: Setup Bun
72-
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
14+
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
7315
with:
7416
bun-version: 1.4.2
75-
76-
# Electron, electron-builder and Playwright download their binaries on every cold install. All
77-
# three caches are keyed by version inside, so an older entry restored by prefix is harmless.
78-
- name: Cache Electron and Playwright downloads
79-
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5
80-
with:
81-
path: |
82-
~/Library/Caches/electron
83-
~/Library/Caches/electron-builder
84-
~/Library/Caches/ms-playwright
85-
key: desktop-downloads-${{ runner.os }}-${{ hashFiles('bun.lock') }}
86-
restore-keys: desktop-downloads-${{ runner.os }}-
87-
88-
- name: Install dependencies
89-
run: bun install --frozen-lockfile
90-
91-
- name: Bundle main and preload
92-
working-directory: apps/desktop
93-
run: bun run build
94-
95-
- name: Install system-browser fixture
96-
working-directory: apps/desktop
97-
run: bunx playwright install chromium
98-
99-
# The terminal-cancel suite drives a real tmux server; without tmux its tmux scenarios skip.
100-
- name: Install tmux
101-
run: brew install tmux
102-
103-
- name: Run Playwright _electron smoke suite
104-
working-directory: apps/desktop
105-
run: bunx playwright test
106-
env:
107-
BACKGROUND_EXECUTOR_REPORT_PATH: test-results/background-executor-report.json
108-
TERMINAL_CANCEL_REPORT_PATH: test-results/terminal-cancel-report.json
109-
110-
- name: Upload test results
111-
if: failure()
112-
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
113-
with:
114-
name: desktop-e2e-results-pinned
115-
path: apps/desktop/test-results
116-
retention-days: 7
117-
118-
e2e-canary:
119-
name: e2e-canary
120-
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
121-
runs-on: macos-26
122-
timeout-minutes: 30
123-
continue-on-error: true
124-
steps:
125-
- name: Checkout code
126-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
127-
with:
128-
persist-credentials: false
129-
130-
- name: Setup Bun
131-
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
132-
with:
133-
bun-version: 1.4.2
134-
135-
# Electron, electron-builder and Playwright download their binaries on every cold install. All
136-
# three caches are keyed by version inside, so an older entry restored by prefix is harmless.
137-
- name: Cache Electron and Playwright downloads
138-
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5
139-
with:
140-
path: |
141-
~/Library/Caches/electron
142-
~/Library/Caches/electron-builder
143-
~/Library/Caches/ms-playwright
144-
key: desktop-downloads-${{ runner.os }}-${{ hashFiles('bun.lock') }}
145-
restore-keys: desktop-downloads-${{ runner.os }}-
146-
147-
- name: Install dependencies
148-
run: bun install --frozen-lockfile
149-
150-
- name: Switch to electron@latest
151-
working-directory: apps/desktop
152-
run: bun add --no-save -d electron@latest
153-
154-
- name: Bundle main and preload
155-
working-directory: apps/desktop
156-
run: bun run build
157-
158-
- name: Install system-browser fixture
159-
working-directory: apps/desktop
160-
run: bunx playwright install chromium
161-
162-
# The terminal-cancel suite drives a real tmux server; without tmux its tmux scenarios skip.
163-
- name: Install tmux
164-
run: brew install tmux
165-
166-
- name: Run Playwright _electron smoke suite
167-
working-directory: apps/desktop
168-
run: bunx playwright test
169-
env:
170-
BACKGROUND_EXECUTOR_REPORT_PATH: test-results/background-executor-report.json
171-
TERMINAL_CANCEL_REPORT_PATH: test-results/terminal-cancel-report.json
172-
173-
- name: Upload test results
174-
if: failure()
175-
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
176-
with:
177-
name: desktop-e2e-results-latest
178-
path: apps/desktop/test-results
179-
retention-days: 7
180-
181-
package-smoke:
182-
name: package-smoke
183-
if: github.event_name != 'schedule'
184-
runs-on: macos-26
185-
timeout-minutes: 20
186-
steps:
187-
- name: Checkout code
188-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
189-
with:
190-
persist-credentials: false
191-
192-
- name: Setup Bun
193-
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
194-
with:
195-
bun-version: 1.4.2
196-
197-
- name: Setup Node
198-
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6
17+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
19918
with:
20019
node-version: 22
201-
202-
# Electron, electron-builder and Playwright download their binaries on every cold install. All
203-
# three caches are keyed by version inside, so an older entry restored by prefix is harmless.
204-
- name: Cache Electron and Playwright downloads
205-
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5
206-
with:
207-
path: |
208-
~/Library/Caches/electron
209-
~/Library/Caches/electron-builder
210-
~/Library/Caches/ms-playwright
211-
key: desktop-downloads-${{ runner.os }}-${{ hashFiles('bun.lock') }}
212-
restore-keys: desktop-downloads-${{ runner.os }}-
213-
214-
- name: Install dependencies
215-
run: bun install --frozen-lockfile
216-
217-
- name: Bundle and package unsigned
218-
working-directory: apps/desktop
20+
- name: Install the native search dependency
21+
run: sudo apt-get update && sudo apt-get install -y ripgrep
22+
- run: bun install --frozen-lockfile
23+
- name: Run the complete repository test gate
21924
env:
220-
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
221-
run: |
222-
bun run build
223-
bunx electron-builder --mac dir --universal --publish never \
224-
-c.mac.identity=- -c.mac.hardenedRuntime=false
225-
226-
- name: Run packaged Electron smoke suite
227-
working-directory: apps/desktop
25+
VITEST_MAX_WORKERS: '2'
22826
run: |
229-
APP_BUNDLE="$(find release -maxdepth 2 -name '*.app' -print -quit)"
230-
if [ -z "$APP_BUNDLE" ]; then
231-
echo "::error::Packaged app bundle was not found."
232-
exit 1
233-
fi
234-
EXECUTABLE="$(find "$APP_BUNDLE/Contents/MacOS" -maxdepth 1 -type f -perm -111 -print -quit)"
235-
if [ -z "$EXECUTABLE" ]; then
236-
echo "::error::Packaged app executable was not found."
237-
exit 1
238-
fi
239-
SIM_DESKTOP_EXECUTABLE="$EXECUTABLE" bunx playwright test e2e/packaged-smoke.spec.ts
27+
set -o pipefail
28+
bun run test 2>&1 | tee full-test.log
29+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
30+
if: always()
31+
with:
32+
name: desktop-consent-full-test-log
33+
path: full-test.log
34+
retention-days: 7

‎apps/desktop/e2e/browser-page-dialogs.spec.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,12 @@ createRoot(document.getElementById('root')).render(createElement(Fixture));`,
433433
await userInput('#draft')
434434
await panelAction({ action: 'reload' })
435435
await expect(shell.getByRole('button', { name: 'Stay', exact: true })).toBeFocused()
436+
await shell.getByRole('dialog').screenshot({
437+
path: test.info().outputPath('leave-page-modal.png'),
438+
animations: 'allow',
439+
caret: 'initial',
440+
})
441+
await expect(shell.getByRole('button', { name: 'Stay', exact: true })).toBeFocused()
436442
await shell.keyboard.press('Escape')
437443
await expect.poll(pageDialog).toBeNull()
438444
await expect

‎apps/desktop/e2e/executor-sim.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ export async function launch(
462462
app.context().pages().forEach(leaveDialogsToDesktop)
463463
app.context().on('page', leaveDialogsToDesktop)
464464
const window = await app.firstWindow()
465+
await window.waitForURL((url) => url.origin === sim.origin, { waitUntil: 'load' })
465466
return { app, window }
466467
}
467468

‎apps/desktop/e2e/local-files.spec.ts‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,12 @@ createRoot(document.getElementById('settings')).render(
316316
})
317317
const shown = app.waitForEvent('window')
318318
await permission.prompt
319-
.getByRole('button', { name: 'Allow all files…', exact: true })
319+
.getByRole('button', { name: 'Full file access', exact: true })
320320
.click({ noWaitAfter: true })
321321
const confirmation = await shown
322322
calls.expiringFullAccess = undefined
323323
await confirmation
324-
.getByRole('button', { name: 'Allow all files', exact: true })
324+
.getByRole('button', { name: 'Enable', exact: true })
325325
.click({ noWaitAfter: true })
326326
expect(await permission.result).toMatchObject({ ok: false })
327327
expect(
@@ -347,7 +347,7 @@ createRoot(document.getElementById('settings')).render(
347347
const permission = await requestPermission({ operation: 'read', toolCallId: 'fullAccess' })
348348
const confirmationShown = app.waitForEvent('window')
349349
await permission.prompt
350-
.getByRole('button', { name: 'Allow all files…', exact: true })
350+
.getByRole('button', { name: 'Full file access', exact: true })
351351
.click({ noWaitAfter: true })
352352
const confirmation = await confirmationShown
353353
await expect(confirmation.getByRole('button', { name: 'Cancel', exact: true })).toBeFocused()
@@ -365,14 +365,14 @@ createRoot(document.getElementById('settings')).render(
365365
).toMatchObject({ fullFileAccess: false })
366366
const acceptedConfirmation = app.waitForEvent('window')
367367
await folderPrompt
368-
.getByRole('button', { name: 'Allow all files…', exact: true })
368+
.getByRole('button', { name: 'Full file access', exact: true })
369369
.click({ noWaitAfter: true })
370370
const allowAll = await acceptedConfirmation
371371
await allowAll.screenshot({
372372
path: test.info().outputPath('full-file-access-confirmation.png'),
373373
})
374374
await allowAll
375-
.getByRole('button', { name: 'Allow all files', exact: true })
375+
.getByRole('button', { name: 'Enable', exact: true })
376376
.click({ noWaitAfter: true })
377377
expect(await permission.result).toMatchObject({
378378
ok: true,
@@ -939,7 +939,10 @@ createRoot(document.getElementById('settings')).render(
939939
try {
940940
await toggle.click()
941941
await expect(
942-
window.getByText('Could not update file access', { exact: true })
942+
window.getByText(
943+
'Could not save file access settings. Your previous setting may return after restarting Sim.',
944+
{ exact: true }
945+
)
943946
).toBeVisible()
944947
await expect(toggle).not.toBeChecked()
945948
expect(

‎apps/desktop/e2e/smoke.spec.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ test.describe('desktop shell smoke', () => {
138138
test('OAuth popups share the session without inheriting the privileged preload', async () => {
139139
app = await launchApp(origin)
140140
const window = await app.firstWindow()
141+
await window.waitForURL(`${origin}/home`, { waitUntil: 'load' })
141142
await window.evaluate(() => {
142143
document.cookie = 'sim-e2e-session=shared; Path=/; SameSite=Lax'
143144
})
@@ -319,7 +320,7 @@ test.describe('desktop shell smoke', () => {
319320
await window.locator('#server').click()
320321
const picker = await pickerPromise
321322

322-
expect(picker.url()).toBe('sim-shell://pages/server.html')
323+
await expect(picker).toHaveURL('sim-shell://pages/server.html')
323324
await expect(picker.getByRole('dialog', { name: 'Sim server', exact: true })).toBeVisible()
324325
await expect(picker.getByLabel('Server URL')).toHaveValue('http://127.0.0.1:1')
325326
await expect(picker.getByLabel('Server URL')).toBeFocused()

‎apps/desktop/src/main/desktop-settings.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ export function createDesktopSettingsService(
187187
if (!deps.config.flush()) {
188188
deps.config.set('fullFileAccess', false)
189189
deps.onFullFileAccessChanged?.(read())
190-
throw new Error('Could not save file access settings')
190+
throw new Error(
191+
'Could not save file access settings. Your previous setting may return after restarting Sim.'
192+
)
191193
}
192194
const preferences = read()
193195
deps.onFullFileAccessChanged?.(preferences)

‎apps/desktop/src/main/local-file-permissions.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export class LocalFilePermissions {
197197
buttons: [
198198
'Allow folder',
199199
"Don't allow",
200-
...(this.enableFullFileAccess ? ['Allow all files…'] : []),
200+
...(this.enableFullFileAccess ? ['Full file access'] : []),
201201
],
202202
defaultId: 1,
203203
cancelId: 1,
@@ -209,10 +209,10 @@ export class LocalFilePermissions {
209209
if (result.response === 2 && this.enableFullFileAccess) {
210210
const confirmation = {
211211
signal,
212-
title: 'Allow full file access?',
212+
title: 'Enable full file access?',
213213
message: `Sim can read and import files from any folder on this computer across chats on ${context.origin}.`,
214214
detail: 'Turn this off in Settings → Desktop → Full file access.',
215-
buttons: ['Allow all files', 'Cancel'],
215+
buttons: ['Enable', 'Cancel'],
216216
defaultId: 1,
217217
cancelId: 1,
218218
}

‎apps/sim/app/workspace/[workspaceId]/settings/components/desktop/desktop.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export function Desktop() {
7777
const { pending: fullFileAccessPending, mutate: setFullFileAccess } =
7878
useDesktopPreferenceMutation(
7979
async (bridge, enabled: boolean) => bridge.settings.setFullFileAccess?.(enabled),
80-
'Could not update file access',
80+
'Could not save file access settings. Your previous setting may return after restarting Sim.',
8181
setPreferences
8282
)
8383

0 commit comments

Comments
 (0)