Files
orca/config/scripts/orcad-mobile-web-bundle.test.mjs
T
Jinwoo Hong 776c791554 feat(orcad): ship the mobile web page so phones paired to orcad get it (#29882)
* feat(orcad): ship the mobile web page so phones paired to orcad get it

orcad never carried out/mobile-web, so it did not advertise
mobileWeb.bundle.v1 and phones paired directly to an orcad server fell
back to the app's built-in native screens.

The built page now ships in every orcad package at out/mobile-web, the
path getBundledMobileWebBundleRoot already probes under the install
root. Its manifest is a fixed artifact; its content-addressed assets
join the hashed artifact list from that manifest, as one shared copy in
the template's common files. build-orcad fails when the page is missing
or stale, and CI lanes that build orcad now build the page first.

* ci(orcad): check out mobile/ for the Windows host template build

* refactor(orcad): copy the page tree whole and build it once per CI run

The guard already refuses unlisted files, so staging copies the
bundle directory as native-chat-visuals is copied. The shipped template
takes the page the qualification lanes tested, the e2e build artifact
carries it, and the PR smoke builds it through install-mobile-dependencies
behind its own scope step. Drops tests that duplicated the guard's own.

* fix(orcad): refuse a template page asset name that escapes the slot
2026-10-16 19:29:41 -07:00

60 lines
2.3 KiB
JavaScript

import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { parse } from 'yaml'
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
import { ORCAD_MOBILE_WEB_MANIFEST } from '../../src/shared/orcad-artifacts.ts'
import { writeMobileWebBundleFixtureTree } from './mobile-web-bundle-fixture-tree.mjs'
import {
readOrcadMobileWebAssetFilenames,
stageOrcadMobileWebBundle
} from './orcad-mobile-web-bundle.mjs'
let scratch
let bundleDir
let outputDir
beforeEach(() => {
scratch = mkdtempSync(join(tmpdir(), 'orcad-mobile-web-'))
bundleDir = join(scratch, 'mobile-web')
outputDir = join(scratch, 'orcad')
vi.spyOn(console, 'log').mockImplementation(() => {})
})
afterEach(() => {
vi.restoreAllMocks()
rmSync(scratch, { recursive: true, force: true })
})
it('stages the manifest and every asset it lists, byte for byte', async () => {
const { manifest } = await writeMobileWebBundleFixtureTree({ outDir: bundleDir })
stageOrcadMobileWebBundle(outputDir, bundleDir)
const staged = readOrcadMobileWebAssetFilenames(outputDir)
expect(staged).toHaveLength(manifest.assets.length)
for (const asset of manifest.assets) {
expect(readFileSync(join(outputDir, 'out', 'mobile-web', asset.path))).toEqual(
readFileSync(join(bundleDir, asset.path))
)
}
expect(readFileSync(join(outputDir, ORCAD_MOBILE_WEB_MANIFEST))).toEqual(
readFileSync(join(bundleDir, 'manifest.json'))
)
})
it('fails the build when the page was never built', () => {
expect(() => stageOrcadMobileWebBundle(outputDir, bundleDir)).toThrow('pnpm build:mobile-web')
expect(existsSync(join(outputDir, ORCAD_MOBILE_WEB_MANIFEST))).toBe(false)
})
it('ships the page the qualification lanes tested in the release template', () => {
const workflow = parse(
readFileSync(new URL('../../.github/workflows/node-server-tests.yml', import.meta.url), 'utf8')
)
const template = workflow.jobs.desktop_template
expect(template.needs).toContain('mobile_web_bundle')
expect(template.if).toContain("needs.mobile_web_bundle.result == 'success'")
expect(template.steps.some((step) => step.with?.name === 'orcad-mobile-web-bundle')).toBe(true)
expect(template.steps.some((step) => step.uses?.includes('build-mobile-web-bundle'))).toBe(false)
})