Repository navigation
feat(release): ship the extension zips and settle two flaky fill tests - #17
Merged
Merged
Conversation
Both failures were races in the tests, not in the extension. openPopup loaded popup.html in a tab that was active at the time, and the tests brought the fixture to the front only afterwards. The popup's first get-state answers for the active tab, and chrome.tabs.query hides the url of a chrome-extension:// tab, so a get-state that ran first got "No active page" and the popup never listed an option. openPopup now takes the page under test and brings it to the front before popup.html loads, so the popup loads in a background tab and its first get-state sees that page. generateAndFill fills the page before it calls save-login, so a log read taken as soon as #password held the generated value could run before the fake app had logged save-login. Both generate tests now wait for the popup's "Password saved to Subclave" notice, which shows only after save-login has answered. Closes #15
A tagged release shipped only the desktop installers, so getting the extension meant building it from source or fetching a CI artifact that expires after 7 days. The new publish-extension job runs after create-release. It builds the chrome and firefox targets, zips them with the same commands as CI's extension job, and uploads subclave-chrome.zip and subclave-firefox.zip into the draft by release_id, as tauri-action does: a re-run creates a second draft for the same tag, so a lookup by tag could pick the wrong one. It needs no Rust toolchain and no proxy build. README.md gains an install section: Load unpacked on Chromium browsers, with the pinned ID fbefjngeldidlcdilbigapddeimhklpn and the manual update, and on Firefox a temporary add-on on release and Beta or a file install with signatures off on ESR, Developer Edition and Nightly. KNOWN-LIMITS.md records the manual install and update; SUBCLAVE.md's release workflow mentions the zips. Closes #16
This was referenced Oct 6, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The two
fill.spec.tspopup tests that failed intermittently in CI aresettled, and a tagged release now attaches
subclave-chrome.zipandsubclave-firefox.zipto its draft, with install steps in the README.Why
Closes #15. Closes #16.
meant building it from source or fetching a CI artifact that expires after
7 days.
How
Flaky tests (#15)
openPopup(extension/test/support/harness.ts) takes the page under testas
frontand brings it to the front beforepopup.htmlloads. Before, thepopup loaded while its own tab was active and the test brought the fixture to
the front afterwards. The popup's first
get-stateanswers for the activetab, and
chrome.tabs.queryhides theurlof achrome-extension://tab,so a
get-statethat ran first got "No active page". The popup asks onlyonce, on mount, so no option ever rendered. The popup now loads in a
background tab, and its first
get-statesees the page under test.fill.spec.tsandinline.spec.tsthat has a pageunder test passes it, and the
bringToFront()that followed the load isgone. The locked and not-running tests and the service worker restart test
in
save.spec.tskeep the bare call: they never read the active tab's URL.generateAndFillfills the page before it callssave-login, so a log readtaken as soon as
#passwordheld the generated value could run before thefake app had logged
save-login. "generates a password, fills the signupform and saves a new entry" and "offers an update per match and keeps the
entry id" now wait for the popup's "Password saved to Subclave" notice,
which shows only after
save-loginhas answered. The first of the two hadthe same race but had not failed in CI yet.
extension/src/.Extension zips in the release (#16)
publish-extensionjob in.github/workflows/release.yml:needs: create-release, onubuntu-latest, with the same pnpm 10 andNode 24 setup as
publish-tauriand the build and zip commands from CI'sextensionjob. Anactions/github-scriptstep uploads both zips byrelease_id, as tauri-action does: a re-run creates a second draft for thesame tag, so a lookup by tag could pick the wrong one. A missing zip fails
the job. It runs neither Playwright nor
web-ext lint, because CI alreadyran both on the tagged commit.
README.md: "Install the browser extension", between Status and Build fromsource.
hand.
xpinstall.signatures.requiredoff on ESR, Developer Edition and Nightly.KNOWN-LIMITS.mdrecords the manual install and update until the extensionis on the Chrome Web Store and signed by Mozilla.
SUBCLAVE.md's releaseworkflow mentions the zips.
Testing
Race 1, forced: a 1500 ms wait after the popup's
gotoin the oldopenPopupmakes "a page load opens no connection and the first popup fillopens one" time out at
getByRole('option')(fill.spec.ts:260), the CIfailure. The same wait in the new
openPopuppasses.Race 2, forced: a 1000 ms delay in the fake app's
save-loginmakes bothgenerate tests fail in both projects, with
Expected: "entry-2",Received: undefinedandExpected: "newuser",Received: undefined. Withthe notice wait, all four runs pass with the delay still in place. Neither
delay is in this PR.
pnpm --filter subclave-extension test: 83/83.pnpm --filter subclave-extension test test/fill.spec.ts --repeat-each=5:140/140.
pnpm exec tsc --noEmit,pnpm run typecheck:extensionandpnpm run format:checkare clean.The new job's build and zip commands, run locally: both zips hold
manifest.json,background.js,content.js,popup.html,popup.js,popup.cssand the icons. The unzipped Chrome build, loaded in Playwright'sChromium, gets the ID
fbefjngeldidlcdilbigapddeimhklpn.pnpm exec tsc --noEmitcleanManual smoke-test of the affected feature
(If you touched
src-tauri/)cargo checkclean(If UI) tested in
pnpm tauri:dev(isolated dev data dir)No changes under
src-tauri/and no app UI change.Not tested yet:
v*tag run. The next tag is the first realcheck of Releases ship no browser extension, so installing it means building from source #16's release half.
.zip, and whether a temporary add-on stays paired across a restart. TheREADME's "pair again" line holds either way.
Screenshots / GIFs
None. No UI change.
Notes for reviewer
release.ymlby handwould create a real draft release, so it waits for the next tag.