Skip to content

WT-841 Show correct Windows download link#1152

Open
bluewave41 wants to merge 8 commits into
mainfrom
WT-841-windows-arch
Open

WT-841 Show correct Windows download link#1152
bluewave41 wants to merge 8 commits into
mainfrom
WT-841-windows-arch

Conversation

@bluewave41
Copy link
Copy Markdown
Collaborator

@bluewave41 bluewave41 commented Mar 16, 2026

One-line summary

Windows users are shown the 32 bit download link on https://www.mozilla.org/firefox/installer-help/?channel=release regardless of their current architecture.

Issue / Bugzilla link

https://bugzilla.mozilla.org/show_bug.cgi?id=1564333

Testing

Before each step remember to change the HTML class OS to "windows"
The x64 doesn't matter as it doesn't affect the shown download button. Only "win" is ever displayed

@bluewave41 bluewave41 force-pushed the WT-841-windows-arch branch from d4abde9 to 8d4547c Compare March 16, 2026 18:30
@bluewave41 bluewave41 changed the title WT 841 windows arch WT-841 Show correct Windows arch Mar 16, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 75.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 79.30%. Comparing base (f605e65) to head (4290c24).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
springfield/firefox/views.py 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1152      +/-   ##
==========================================
+ Coverage   79.25%   79.30%   +0.04%     
==========================================
  Files         135      137       +2     
  Lines        8375     8428      +53     
==========================================
+ Hits         6638     6684      +46     
- Misses       1737     1744       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bluewave41 bluewave41 changed the title WT-841 Show correct Windows arch WT-841 Show correct Windows download link Mar 16, 2026
@janbrasna
Copy link
Copy Markdown
Collaborator

Just proxying Hector's note from mozilla/bedrock#8635 (comment) for visibility.

The TL;DR is the true x64 bitness is not provided by all user agents and is therefore not reliable. There should be a new query parameter available now locking the actual arch used for the installation that pointed back to this page.

@maureenlholland
Copy link
Copy Markdown
Collaborator

@janbrasna do you know how we can trigger the installer_arch param for testing? (Otherwise, I guess we just assume it will be there and use test urls that already include the installer_arch param)

@janbrasna
Copy link
Copy Markdown
Collaborator

I believe it comes from within in-product flow, either from the stub installer unable to install, or the in-product updater not able to update(?) — @l-hedgehog Would you know how to trigger that for testing? (or who to ask on the installer team? TY)

For the NSIS patch linked it's this: https://github.com/mozilla-firefox/firefox/blob/c1e060fc/browser/installer/windows/nsis/stub.nsh#L98-L101 so IIUC the archs are passed as literal installer_arch=1 installer_arch=2 installer_arch=3 values in that URL?

@l-hedgehog
Copy link
Copy Markdown

@janbrasna Essentially you'll have to somehow interrupt the stub installer while it's downloading the full installer in the background. I guess you could try just disabling the network during that phase, or if the download finishes too quick to test, maybe adding an entry to hosts file and point downloads.mozilla.org to localhost.

@maureenlholland
Copy link
Copy Markdown
Collaborator

IIUC the archs are passed as literal installer_arch=1 installer_arch=2 installer_arch=3 values in that URL?

That's my understanding too. Thanks both for the tips.

@bluewave41 for development I think the easiest route will be testing directly with the installer arch params:

  • 192.168.x.x:8000/download/installer-help/?channel=release&installer_arch=1 (32-bit)
  • 192.168.x.x:8000/download/installer-help/?channel=release&installer_arch=2 (64-bit)
  • 192.168.x.x:8000/download/installer-help/?channel=release&installer_arch=3 (AARCH64)

We can try triggering from interrupting the stub installer to confirm these urls but I think it's safe to assume we can rely on the expected params being there

@bluewave41
Copy link
Copy Markdown
Collaborator Author

bluewave41 commented Mar 18, 2026

Ahh I get the full scope now.

Blocking /etc/hosts on Windows with: 127.0.0.1 download.mozilla.org

Brings you to this URL once pressing the OK/continue button when asked to retry.

www.firefox.com/en-US/download/installer-help/?redirect_source=mozilla-org&channel=release&installer_lang=en-US&installer_arch=x

@bluewave41 bluewave41 marked this pull request as draft March 18, 2026 21:08
@janbrasna
Copy link
Copy Markdown
Collaborator

"This feels a little bit like cheating as the page has elements for win, win64 and win64-aarch divs specifically but I don't see an easy way to target the aarch64 div as the classes on HTML only support nothing and x64. I don't think it's worth going through and adding support for also showing aarch64 when it's most likely only going to be used on this page."

OK that's kind of a good point. Let's cheat differently. Could you turn the extra query arg into a new body/html class (wherever is easier to reach from the jinja context you'll be touching) — say "force-win64" based on the arg — and then just hide all .force-win64 .os_* combinations via specificity, and only show .force-win64 .os_win64 back? (That could theoretically even override the platform user agent sniffing to make sure it always positively selects from windows buttons if the URL specifies coming from windows stub;D) — That way you create your own namespace for the classes so you can define e.g. .force-win64arm .os_win64-aarch64 to show just based on what you put there already in the template based on the URL query, even though the current Client JS body classes don't expose that per se, and you won't need it to that way.

@bluewave41 bluewave41 force-pushed the WT-841-windows-arch branch from 7f8cc68 to 406ca56 Compare March 18, 2026 23:23
@bluewave41
Copy link
Copy Markdown
Collaborator Author

"This feels a little bit like cheating as the page has elements for win, win64 and win64-aarch divs specifically but I don't see an easy way to target the aarch64 div as the classes on HTML only support nothing and x64. I don't think it's worth going through and adding support for also showing aarch64 when it's most likely only going to be used on this page."

OK that's kind of a good point. Let's cheat differently. Could you turn the extra query arg into a new body/html class (wherever is easier to reach from the jinja context you'll be touching) — say "force-win64" based on the arg — and then just hide all .force-win64 .os_* combinations via specificity, and only show .force-win64 .os_win64 back? (That could theoretically even override the platform user agent sniffing to make sure it always positively selects from windows buttons if the URL specifies coming from windows stub;D) — That way you create your own namespace for the classes so you can define e.g. .force-win64arm .os_win64-aarch64 to show just based on what you put there already in the template based on the URL query, even though the current Client JS body classes don't expose that per se, and you won't need it to that way.

That was my first thought but it seemed like I was touching a larger scope than I wanted to for something that will only be used on a single page.

I replaced my code with a commit that adds an aarch64 class that gets applied in place of x64 based on installer_arch since I think it makes sense to consider it a different architecture. With this we can just hide the os_win div and instead show the os_win64-aarch64 one which feels less cheaty.

I think with this we should be able to also use user agent sniffing to apply the aarch64 class correctly as a quick Google search says they display like Mozilla/5.0 (Windows NT 10.0; ARM64; RM-1096) AppleWebKit/537.36 (KHTML like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393

@l-hedgehog
Copy link
Copy Markdown

That was my first thought but it seemed like I was touching a larger scope than I wanted to for something that will only be used on a single page.

I think you're now offering win64 installers not only for installer_arch=2, but also when .windows.x64 is applied by site.js. I believe the latter was deliberately not the case and should stay that way.

@bluewave41
Copy link
Copy Markdown
Collaborator Author

That was my first thought but it seemed like I was touching a larger scope than I wanted to for something that will only be used on a single page.

I think you're now offering win64 installers not only for installer_arch=2, but also when .windows.x64 is applied by site.js. I believe the latter was deliberately not the case and should stay that way.

Gotcha so.

No installer_arch = win32 always
installer_arch=1 = win32
installer_arch=2 = win64
installer_arch=3 = win64-aarch64

@bluewave41 bluewave41 force-pushed the WT-841-windows-arch branch from d32296d to 04d7e72 Compare March 19, 2026 16:25
@bluewave41 bluewave41 marked this pull request as ready for review March 19, 2026 16:39
@maureenlholland maureenlholland self-assigned this Mar 25, 2026
Copy link
Copy Markdown
Collaborator

@maureenlholland maureenlholland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the installer arch work looks good to me 🎉

one blocking issue on Nightly download button for http://localhost:8000/en-US/channel/desktop/

We should confirm this PR passes existing integration tests before merge: https://mozmeao.github.io/platform-docs/operations/pipeline/#pushing-to-the-integration-tests-branch
(^ this may require some permissions you don't yet have, if you are blocked here, ask in www slack for permissions)

With any new download functionality, we should also add new tests

Jasmine is probably the best for the new logic in site.js, but we might need to adjust or update Playwright to confirm the channel page download functionality too

display: none !important;
}

.windows.x64 .download-button .os_win64 {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (blocking): we've lost the nightly button on channels pages for 64-bit. It doesn't show up in the download list either, so it's not a CSS display issue.

Image

Beta & dev for 64-bit are fine. No issues with aarch64 or 32-bit on any of these channels either.

@maureenlholland
Copy link
Copy Markdown
Collaborator

@janbrasna
Copy link
Copy Markdown
Collaborator

Could you turn the extra query arg into a new body/html class (wherever is easier to reach from the jinja context you'll be touching) — say "force-win64" based on the arg — and then just hide all .force-win64 .os_* combinations via specificity, and only show .force-win64 .os_win64 back? […] — That way you create your own namespace for the classes […]

That was my first thought but it seemed like I was touching a larger scope than I wanted to for something that will only be used on a single page.

I perhaps forgot to mention only adding that template class override only for that one specific page where it's expected to be parsing the query string. Haven't checked actual feasibility in terms of what view handles that and how easy is to add the request args to the render context etc., so that was mainly thinking out loud, how to contain the change within the targeted page as much as possible.

I replaced my code with a commit that adds an aarch64 class that gets applied in place of x64 based on installer_arch since I think it makes sense to consider it a different architecture.

That however sounds like this could affect any page running site.js, if a query param is added to any such arbitrary page?

(Also, the issues surfaced by integration tests on other pages not subject to this change per se means the potential to change CTAs behavior is currently site-wide.)

Why I'm mentioning it is, without deeper understanding of when the stub vs. latest installer is chosen for any given CTA, in most cases the ideal version served for os_win is the small 32bit stub installer, that then itself picks the right arch once run on the target system — which normally is the preferred even for x64 and arm64 — until it fails, and then points towards the /installer-help page — which should probably be the only place that ought to enforce an arch, compared to other CTA buttons around the site. That's just a comment regarding touching site-wide functionality, compared to just something contained in plain querystring → template class → style/visibility overrides over any Client/site.js classes applied just for this one specific template. (But I'll defer to reviewer for advice.)

I think with this we should be able to also use user agent sniffing to apply the aarch64

It was not included in the Client/site.js because it is not exposed and most user agent strings realistically just freeze the values, or, was not deemed reliable even when using the JS navigator data. It might work for some browsers using client-hints, but e.g. will definitely not work if opened in Firefox. The code used to be there, but was never used: mozilla/bedrock#8454 (comment)

@bluewave41 bluewave41 force-pushed the WT-841-windows-arch branch from 04d7e72 to 36b9526 Compare March 31, 2026 18:36
@bluewave41 bluewave41 marked this pull request as draft March 31, 2026 19:58
@bluewave41 bluewave41 marked this pull request as ready for review March 31, 2026 22:09
@bluewave41 bluewave41 marked this pull request as draft March 31, 2026 22:22
@bluewave41
Copy link
Copy Markdown
Collaborator Author

After all the feedback and such I stepped back and scrapped what I had to restart.

I've scoped it now to just the download-list portion of the page. No more site.js the classes only apply to this specific page.

I removed some code someone added to only show the win button for nightly builds. I don't see why this was singled out only for nightly? It causes issues when trying to show the correct link based on installer_arch as the win64 entry no longer exists there. This also removes a test that checks for a smaller number of entries for the nightly channel. This doesn't make sense anymore as it needs to exist on every combination.

@bluewave41 bluewave41 marked this pull request as ready for review April 1, 2026 22:27
@janbrasna
Copy link
Copy Markdown
Collaborator

Hmmh, that might need checking the resulting bouncer links do what they should do and download the expected thing. What this does currently in prod is this: (compare the separate 32b vs 64b stubs for Release, but just a combined 32b/64b in the Nightly list)

channels

Maybe it's just stale logic, and would be correct to challenge it. But there still might be reasons for special casing either way. (Also, notably, the buttons might/would have different labels, thus l10n; so just a heads up if they start pointing to something else, the label does not state the old thing still.)

@bluewave41
Copy link
Copy Markdown
Collaborator Author

Hmmh, that might need checking the resulting bouncer links do what they should do and download the expected thing. What this does currently in prod is this: (compare the separate 32b vs 64b stubs for Release, but just a combined 32b/64b in the Nightly list)

channels

Maybe it's just stale logic, and would be correct to challenge it. But there still might be reasons for special casing either way. (Also, notably, the buttons might/would have different labels, thus l10n; so just a heads up if they start pointing to something else, the label does not state the old thing still.)

Do you mind sharing how I get to this exact page setup? I've been trying to dig into it but I haven't found the exact page that displays the buttons in a list like this.

@janbrasna
Copy link
Copy Markdown
Collaborator

Right I knew I wanted to add more notes to the above, incl. specifically mentioning how I'm forcing the CTAs to show, sorry forgot — basically that should be the underlying nonJS version, or, shown in cases no supported UA is detected. I usually use Focus iOS for that, which has a weird enough UA;D — but the easiest is "non matching" products, e.g. opening Nightly or ESR release from iOS, as these do not have a product for iOS — so all other options get listed instead. Responsive mode with iPad UA should do the trick for you: (reload after changing the device/UA to force new parsing)

responsive

(I also wanted to understand the linked tickets with reasoning when the special casing was added back then, still catching up on code archaeology, will post what I learn.)

@janbrasna
Copy link
Copy Markdown
Collaborator

@bluewave41
Copy link
Copy Markdown
Collaborator Author

Another thing I think is worth pointing out as I catch up on these bugs is the 32 and 64 bit stub installers on https://www.firefox.com/en-US/firefox/149.0/releasenotes/ are both the same file. The OS detection in the stub isn't just nightly specific. I'm still reading to try and find out why this was only done for nightly

@janbrasna
Copy link
Copy Markdown
Collaborator

Hmmh right, download.mozilla.org/?product=firefox-stub&os=win64&lang=en-US and download.mozilla.org/?product=firefox-stub&os=win&lang=en-US serve the exact same binary, true. Because, well, there's no 64-only stub installer; compare:

Notably, this Nightly special casing comes from Fx 54~era, and mostly likely before bouncer; when bedrock linked the FTP archive downloads directly, so it was doing its own logic. Maybe that was the first universal stub and the subsequent Release channel was supposed to follow the same the riding trains? Maybe all of that is completely noop these days, and should be left to what release above does, serve the same for both … or, dunno, maybe the extra buttons although serving the same bouncer link most of time can be forced to point to full installer instead, and THEN they are helpful there's more of them? But yea good call pointing this out, this had been godfathered from redesign to redesign, and nobody really wanted to touch it, but it seems outdated these days — or, the difference between nightly and the rest looks weird (even though the nightly combo makes more sense in a way).

Copy link
Copy Markdown
Collaborator

@maureenlholland maureenlholland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a well-scoped update for the installer-arch pages

  • new force arch param on download helper defaults to None
  • only the installer arch page calls the helper with force arch argument
  • "force-" css classes will only take effect when force arch is not None

I don't have any context to add around the Nightly special casing. It seems like a docs update might be helpful here if we need to keep it.

r+ but will call in another dev to check on the Nightly case

await expect(downloadButtonRelease).toBeVisible();
});

test('Download Firefox (Windows) forced win64 architecture', async ({
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking is it also worth checking the unexpected win downloads are not visible?

# Firefox Nightly: The Windows stub installer is now universal,
# automatically detecting a 32-bit and 64-bit desktop, so the
# win64-specific entry can be skipped.
if channel == "nightly":
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stevejalim do you know if this special casing is still necessary (related tests here: https://github.com/mozmeao/springfield/pull/1152/changes#diff-787fdc6db4abb92a972f332cdf45bf50fbe8d61618b74f507a937285e8ff6139L173)

More detail in comments: #1152 (comment)

Copy link
Copy Markdown
Collaborator Author

@bluewave41 bluewave41 Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping this behavior makes it confusing and would make the CSS look worse

Release
installer_arch=1? show .win
installer_arch=2? show .win64
installer_arch=3? show .win64-aarch64

Nightly
installer_arch=1? show .win
installer_arch=2? show nothing. win64 sets the platform to win but arch 2 shows win64 which doesn't exist
installer_arch=3? show .win64-aarch64

So now we need to specifically CSS nightly and show .win for forced arch 1 and 2. This also means you can't get a 64 bit installer for nightly from this page despite one existing. The stub installers are universal but these full installers are different

https://download-installer.cdn.mozilla.net/pub/firefox/nightly/latest-mozilla-central/firefox-151.0a1.en-US.win32.installer.exe
https://download-installer.cdn.mozilla.net/pub/firefox/nightly/latest-mozilla-central/firefox-151.0a1.en-US.win64.installer.exe

matthew:~/Downloads$ md5sum '/home/matthew/Downloads/firefox-151.0a1.en-US.win64.installer.exe' 
a662d6d7a3d2f19f4d638bf57a5b90bd  /home/matthew/Downloads/firefox-151.0a1.en-US.win64.installer.exe
matthew:~/Downloads$ md5sum '/home/matthew/Downloads/firefox-151.0a1.en-US.win32.installer.exe' 
0140dd3abcbb070f8889d4d8b83fc653  /home/matthew/Downloads/firefox-151.0a1.en-US.win32.installer.exe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants