mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
fix(e2e): launch plugins with real app identity (#11024)
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { dirname } from 'node:path'
|
||||
|
||||
export function getOrcaElectronLaunchArgs(mainPath: string, headful: boolean): string[] {
|
||||
// Launch through package.json so app version and resource paths match a packaged app.
|
||||
const appPath = dirname(dirname(dirname(mainPath)))
|
||||
if (headful || process.platform !== 'linux') {
|
||||
return [mainPath]
|
||||
return [appPath]
|
||||
}
|
||||
|
||||
// Why: Ubuntu CI cannot run Electron's setuid chrome-sandbox (not root-owned
|
||||
@@ -16,6 +20,6 @@ export function getOrcaElectronLaunchArgs(mainPath: string, headful: boolean): s
|
||||
'--disable-gpu-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--in-process-gpu',
|
||||
mainPath
|
||||
appPath
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { join } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { getOrcaElectronLaunchArgs } from './electron-launch-args'
|
||||
|
||||
describe('getOrcaElectronLaunchArgs', () => {
|
||||
it('launches the package root that owns the compiled main entry', () => {
|
||||
const root = join('workspace', 'orca')
|
||||
const mainPath = join(root, 'out', 'main', 'index.js')
|
||||
|
||||
expect(getOrcaElectronLaunchArgs(mainPath, true)).toEqual([root])
|
||||
expect(getOrcaElectronLaunchArgs(mainPath, false).at(-1)).toBe(root)
|
||||
})
|
||||
})
|
||||
@@ -107,12 +107,13 @@ test('runs hello-orca panel, command, and event behind visible consent', async (
|
||||
expect(installed.blocked).toBe(true)
|
||||
|
||||
await openPluginSettings(orcaPage)
|
||||
await orcaPage.getByRole('tab', { name: /^Installed/ }).click()
|
||||
const row = orcaPage.locator(`[data-plugin-key="${installed.pluginKey}"]`)
|
||||
await expect(row).toContainText('Needs review')
|
||||
await row.getByRole('button', { name: 'Review permissions' }).click()
|
||||
await row.getByRole('button', { name: 'Review & enable' }).click()
|
||||
const consent = orcaPage.getByRole('dialog', { name: 'Review permissions' })
|
||||
await expect(consent).toBeVisible()
|
||||
await expect(consent).toContainText(pluginRoot)
|
||||
await expect(consent).toContainText('Local folder')
|
||||
await expect(consent).toContainText('full access to your files, network, and other processes')
|
||||
await expect(consent.getByRole('button', { name: 'Keep Disabled' })).toBeFocused()
|
||||
await consent.getByRole('button', { name: 'Enable plugin' }).click()
|
||||
|
||||
@@ -76,16 +76,10 @@ async function copyLaunchPlugin(
|
||||
|
||||
async function configureFixtureGit(home: string, repositories: string): Promise<NodeJS.ProcessEnv> {
|
||||
const hooksDirectory = join(home, 'hooks')
|
||||
const xdgConfigHome = join(home, 'xdg')
|
||||
const configPath = join(home, '.gitconfig')
|
||||
await Promise.all([
|
||||
mkdir(hooksDirectory, { recursive: true }),
|
||||
mkdir(xdgConfigHome, { recursive: true })
|
||||
])
|
||||
await mkdir(hooksDirectory, { recursive: true })
|
||||
const gitEnvironment: NodeJS.ProcessEnv = {
|
||||
HOME: home,
|
||||
USERPROFILE: home,
|
||||
XDG_CONFIG_HOME: xdgConfigHome,
|
||||
GIT_CONFIG_GLOBAL: configPath,
|
||||
GIT_CONFIG_NOSYSTEM: '1',
|
||||
GIT_TERMINAL_PROMPT: '0'
|
||||
}
|
||||
@@ -184,9 +178,9 @@ async function installMarketplacePluginThroughUi(
|
||||
): Promise<void> {
|
||||
const listing = page.locator(`[data-marketplace-plugin-key="${pluginKey}"]`)
|
||||
await expect(listing).toBeVisible()
|
||||
await listing.getByRole('button', { name: 'Review' }).click()
|
||||
await listing.getByRole('button', { name: 'Install' }).click()
|
||||
const preview = page.getByRole('dialog', { name: pluginName })
|
||||
await expect(preview).toContainText(pluginKey)
|
||||
await expect(preview).toContainText('Official · stablyai')
|
||||
await preview.getByRole('button', { name: 'Install plugin' }).click()
|
||||
const consent = page.getByRole('dialog', { name: consentDialogName })
|
||||
await expect(consent).toBeVisible()
|
||||
@@ -194,6 +188,21 @@ async function installMarketplacePluginThroughUi(
|
||||
await expect(consent).toBeHidden()
|
||||
}
|
||||
|
||||
async function enableInstalledPluginThroughUi(
|
||||
page: Page,
|
||||
pluginKey: string,
|
||||
consentDialogName: string
|
||||
): Promise<void> {
|
||||
await page.getByRole('tab', { name: /^Installed/ }).click()
|
||||
const plugin = page.locator(`[data-plugin-key="${pluginKey}"]`)
|
||||
await expect(plugin).toBeVisible()
|
||||
await plugin.getByRole('button', { name: 'Review & enable' }).click()
|
||||
const consent = page.getByRole('dialog', { name: consentDialogName })
|
||||
await expect(consent).toBeVisible()
|
||||
await consent.getByRole('button', { name: 'Enable plugin' }).click()
|
||||
await expect(consent).toBeHidden()
|
||||
}
|
||||
|
||||
async function applyInstalledLanguage(page: Page): Promise<void> {
|
||||
const languageId = 'plugin:stablyai.orca-portuguese/pt-BR'
|
||||
await page.evaluate(() => {
|
||||
@@ -251,10 +260,9 @@ async function runMarketplaceJourney(page: Page): Promise<void> {
|
||||
'Multipass VM Recipes',
|
||||
'Review plugin content'
|
||||
)
|
||||
await installMarketplacePluginThroughUi(
|
||||
await enableInstalledPluginThroughUi(
|
||||
page,
|
||||
'stablyai.orca-navigation-shortcuts',
|
||||
'Orca Navigation Shortcuts',
|
||||
'Review plugin content'
|
||||
)
|
||||
|
||||
@@ -266,11 +274,7 @@ async function runMarketplaceJourney(page: Page): Promise<void> {
|
||||
test('installs and applies official Phase 1 content from a fresh profile', async ({}, testInfo) => {
|
||||
test.setTimeout(180_000)
|
||||
const fixture = await createMarketplaceFixture()
|
||||
const session = createRestartSession(testInfo as TestInfo, {
|
||||
extraEnv: {
|
||||
...fixture.gitEnvironment
|
||||
}
|
||||
})
|
||||
const session = createRestartSession(testInfo as TestInfo, fixture.gitEnvironment)
|
||||
let launched: Awaited<ReturnType<typeof session.launch>> | null = null
|
||||
try {
|
||||
launched = await session.launch()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { expect, test, type ElectronApplication, type TestInfo } from '@stablyai/playwright-test'
|
||||
import { expect, test, type TestInfo } from '@stablyai/playwright-test'
|
||||
import { fingerprintPluginConsent } from '../../src/shared/plugins/plugin-consent-fingerprint'
|
||||
import { pluginManifestSchema } from '../../src/shared/plugins/plugin-manifest'
|
||||
import { createRestartSession } from './helpers/orca-restart'
|
||||
@@ -84,12 +84,11 @@ async function launchSample(
|
||||
testInfo: TestInfo
|
||||
): Promise<StartupSample> {
|
||||
let output = ''
|
||||
const attachLogs = (app: ElectronApplication): void => {
|
||||
app.process().stderr?.on('data', (chunk: Buffer) => {
|
||||
output += chunk.toString('utf8')
|
||||
})
|
||||
}
|
||||
const launched = await session.launch(attachLogs)
|
||||
const launched = await session.launch({
|
||||
onStderr: (chunk) => {
|
||||
output += chunk
|
||||
}
|
||||
})
|
||||
try {
|
||||
await expect
|
||||
.poll(
|
||||
@@ -127,9 +126,7 @@ function median(values: readonly number[]): number {
|
||||
// oxlint-disable-next-line no-empty-pattern -- Playwright passes fixtures before testInfo.
|
||||
test('keeps real Electron launch stable with 20 approved inert plugins', async ({}, testInfo) => {
|
||||
test.setTimeout(240_000)
|
||||
const session = createRestartSession(testInfo, {
|
||||
extraEnv: { ORCA_STARTUP_DIAGNOSTICS: '1' }
|
||||
})
|
||||
const session = createRestartSession(testInfo, { ORCA_STARTUP_DIAGNOSTICS: '1' })
|
||||
const baseline: StartupSample[] = []
|
||||
const populated: StartupSample[] = []
|
||||
let markerPaths: string[] = []
|
||||
|
||||
Reference in New Issue
Block a user