Skip to content

WT-962: Set as default page in Wagtail#1207

Open
lucianoratamero wants to merge 43 commits intomainfrom
WT-962-set-as-default-page
Open

WT-962: Set as default page in Wagtail#1207
lucianoratamero wants to merge 43 commits intomainfrom
WT-962-set-as-default-page

Conversation

@lucianoratamero
Copy link
Copy Markdown
Collaborator

@lucianoratamero lucianoratamero commented Mar 30, 2026

One-line summary

This PR adds a Set as Default button block and its snippet counterpart, to enable setting your browser as default from anywhere in the app.

Issue / Bugzilla link

https://mozilla-hub.atlassian.net/browse/WT-962

Testing

We added a fixture that creates a freeform page with the set as default button, and adds a test snippet to the db.
Run ./manage.py load_page_fixtures, then navigate to the page (it's inside the Tests Index Page 2026 page), and check that the contents are loaded correctly for every scenario.

We recommend enabling the UI tour locally and using an user agent browser extension to simulate different OSs.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 92.77108% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.83%. Comparing base (b4d3384) to head (fb2d75b).

Files with missing lines Patch % Lines
...ield/cms/management/commands/load_page_fixtures.py 0.00% 4 Missing ⚠️
springfield/cms/fixtures/download_page_fixtures.py 0.00% 1 Missing ⚠️
springfield/cms/models/snippets.py 93.75% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1207      +/-   ##
==========================================
+ Coverage   79.72%   79.83%   +0.10%     
==========================================
  Files         138      138              
  Lines        8644     8706      +62     
==========================================
+ Hits         6891     6950      +59     
- Misses       1753     1756       +3     

☔ 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.

kkellydesign

This comment was marked as outdated.

@lucianoratamero lucianoratamero marked this pull request as ready for review April 3, 2026 19:43
@stevejalim stevejalim requested review from Copilot April 7, 2026 11:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Wagtail snippet + button block to render a “Set Firefox as default” modal, along with conditional-display support for “default browser” state so content can vary based on whether Firefox is already default.

Changes:

  • Introduces SetAsDefaultSnippet (model, templates, preview template) and a new set_as_default_button block type.
  • Extends conditional-display to support default_browser_condition, plus corresponding CSS/JS to toggle the state.
  • Adds fixtures + a new Django test module to validate rendering and fixture behavior.

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
springfield/settings/base.py Adds SET_AS_DEFAULT_SNIPPET_ID setting for fixture/snippet creation.
springfield/cms/tests/test_set_as_default_snippet.py New test coverage for set-as-default block/snippet rendering.
springfield/cms/templates/components/dialog.html Wraps dialog body in .fl-dialog-content-text for styling.
springfield/cms/templates/components/conditional-display.html Adds default_browser_condition wrapper support.
springfield/cms/templates/components/button.html Allows rendering either <a> or <button> + adds data-target-id.
springfield/cms/templates/cms/snippets/set-as-default-snippet.html New snippet template with conditional sections by browser/default/platform.
springfield/cms/templates/cms/snippets/set-as-default-snippet-preview.html New Wagtail preview template for the snippet.
springfield/cms/templates/cms/blocks/sticker-card.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/sticker-card-2026.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/step-card.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/set_as_default_button.html New block template rendering trigger + dialog content from snippet.
springfield/cms/templates/cms/blocks/sections/section.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/sections/kit-banner.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/sections/home-kit-banner.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/sections/home-carousel.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/sections/banner.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/outlined-card.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/notification.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/inline-notification.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/illustration-card.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/illustration-card-2026.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/icon-card.html Passes default_browser_condition through to conditional display.
springfield/cms/templates/cms/blocks/filled-card.html Passes default_browser_condition through to conditional display.
springfield/cms/models/snippets.py Adds the new SetAsDefaultSnippet model + registers it.
springfield/cms/migrations/0060_setasdefaultsnippet.py Migration to create the new snippet model table.
springfield/cms/management/commands/load_page_fixtures.py Loads a new test page fixture that includes the set-as-default button.
springfield/cms/fixtures/whats_new_page_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/topic_list_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/thanks_page_fixtures.py Updates fixture show-to dicts to include default_browser.
springfield/cms/fixtures/snippet_fixtures.py Adds fixture builder for SetAsDefaultSnippet.
springfield/cms/fixtures/notification_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/media_content_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/kit_banner_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/inline_notification_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/icon_list_with_image_2026_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/homepage_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/freeformpage_2026.py Adds a new FreeFormPage2026 fixture including the set-as-default button.
springfield/cms/fixtures/download_page_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/carousel_2026_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/cards_2026_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/card_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/banner_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/fixtures/article_page_fixtures.py Updates fixture show-to dict to include default_browser.
springfield/cms/blocks.py Adds default-browser filtering to ConditionalDisplayBlock + new button/block type.
media/js/cms/new.es6.js Adds UITour-based default-browser detection + analytics + polling.
media/css/cms/flare26-utilities.css Adds conditional-display rules for default-browser state.
media/css/cms/flare26-typography.css Adds standalone Firefox logo styling for the modal header.
media/css/cms/flare26-modal.css Updates dialog close-button offsets + adds dialog body padding utility.
media/css/cms/flare26-intro.css Tweaks .fl-buttons child styling (attempting to avoid dialog layout issues).
media/css/cms/flare26-button.css Tweaks .fl-buttons child styling (attempting to avoid dialog layout issues).
Comments suppressed due to low confidence (3)

springfield/cms/templates/components/button.html:18

  • fix: In the rendering path, this still emits anchor-only attributes when external is set (target/rel). target is invalid on and can cause HTML validation/accessibility issues; condition these attributes on link (or only render them for the branch).
    springfield/cms/blocks.py:456
  • fix: The ConditionalDisplayBlock summary (label_format) doesn’t include the newly added default_browser field, so editors won’t see that condition in the collapsed block label. Update label_format to include {default_browser} to match the available controls.
    default_browser = blocks.ChoiceBlock(
        choices=DEFAULT_BROWSER_CHOICES,
        default="",
        required=False,
        label="Default Browser",
        help_text="Filter by default browser state. Leave empty for no restriction.",
    )

    class Meta:
        label = "Conditional Display"
        label_format = "Conditions: {platforms} - {firefox} - {auth_state}"
        icon = "eye"

media/css/cms/flare26-utilities.css:285

  • bug: condition-unknown content is hidden once a known platform class is present. With default-browser detection, pages add html.firefox-is-not-default, but this selector list only includes html.firefox-is-default, so condition-unknown will remain visible for the not-default case. Add html.firefox-is-not-default to the hide list for condition-unknown (mirroring the default case).
.conditional-display.condition-unknown {
    display: block;
    display: revert;
}

html.firefox-is-default .conditional-display.condition-unknown:not(.is-preview),
html.linux .conditional-display.condition-unknown:not(.is-preview),
html.osx .conditional-display.condition-unknown:not(.is-preview),
html.windows .conditional-display.condition-unknown:not(.is-preview),
html.windows-10-plus .conditional-display.condition-unknown:not(.is-preview),
html.ios .conditional-display.condition-unknown:not(.is-preview),
html.other .conditional-display.condition-unknown:not(.is-preview),
html.android .conditional-display.condition-unknown:not(.is-preview) {
    display: none;
}

Comment thread springfield/cms/blocks.py
Comment thread springfield/cms/templates/cms/blocks/set_as_default_button.html
Comment thread media/js/cms/new.es6.js Outdated
Comment thread media/js/cms/new.es6.js Outdated
Comment thread springfield/cms/models/snippets.py
Comment thread media/css/cms/flare26-button.css Outdated
Comment thread media/css/cms/flare26-intro.css Outdated
Comment thread springfield/cms/blocks.py
Copy link
Copy Markdown
Collaborator

@kkellydesign kkellydesign left a comment

Choose a reason for hiding this comment

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

  • Remove the empty heading P if there's no content.
  • left-align text if there's an icon present.
Image

@kkellydesign
Copy link
Copy Markdown
Collaborator

Screenshot 2026-04-09 at 10 58 08 AM

There's a rogue <p></p> too. We probably another conditional somewhere.

@kkellydesign
Copy link
Copy Markdown
Collaborator

One brief tweak: let's make the "success" message inline, so if the user is already set to default on page load, they don't have to click on a modal to see it. Thoughts?

Screenshot 2026-04-09 at 12 16 45 PM

@tesseheinricks
Copy link
Copy Markdown

Taking a look now! Excellent work! Recording notes below:

  1. Are we able to change functionality so that the thanks modal closes with the X button and clicking outside of the modal (anywhere on the overlay)?
  2. Any ways to smooth the transitions slightly?
  3. Can we utilize the purple modal styling as opposed to the green?

I'm also only seeing the modal upon completion, where / when am I supposed to see the success toast.

If we have to choose between experiences, I would recommend:

  • The purple success notification shows for a set duration at top of page after setting as default. No pop-up modal
  • What becomes of the primary CTA button? After a user has changes to Firefox as default this button should disappear or transition to support related content in case of error

Let me know if you have any questions and thank you!

@lucianoratamero
Copy link
Copy Markdown
Collaborator Author

I fixed the text align on notifications, thanks for catching that @kkellydesign !

answering @kkellydesign :

about the modal: currently, both the dialog open and the set as default function triggers are tied to the user clicking the button. we could change the behavior so that the only trigger is the set as default function; and if it detects that we're on FF Desktop (it only works on that combination), we could just not open the modal at all, leaving the modal open conditional to anything that's not FF Desktop.

we would lose an important bit of info though: it might be the case that the set as default function fails on FF Desktop (I could 100% see this happening on linux), and since the message of "if something went wrong, click here for the docs" is in the modal, the user would never see it. there are possible workarounds, and we can discuss this better on slack, but for this reason alone, I think keeping everything in one spot is better, even though I agree that a modal is not ideal.

answering @tesseheinricks :

besides the topic above, I'll answer by topic:

  1. yes! the code currently doesn't do that, but it's totally doable. I think it could even be the default, as well as pressing Esc to dismiss. what do you think?
  2. we can, but what are you thinking for the transition? maybe a 300ms fade in?
  3. I'm not sure what you mean by purple modal styling. the modal is white on light mode and purple on dark. are you referring to the notification message?

one more thing to everyone:

I'm not fond of the notification being rendered inside of the modal. maybe the answer is to either do a notification pop-up outside of the modal and close it on success, or just show a success message inline, inside of the modal.
thoughts?

(also, sorry for the long text :B)

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.

5 participants