Wednesday, September 16, 2026
7 changes · saas-19.3
Resolved issues and error corrections
This fixes automated website builder checks so they continue to work with newer Chrome behavior when reading background image sizing. It helps keep release validation stable without changing the website experience for users.
Original PR description
In Chrome 152, single-value `background-size` properties may be serialized or expanded to include implicit dimensions (e.g., appending `auto` like `100px auto`), causing strict exact-string test assertions to fail. This commit updates `website` builder test expectations to use regex prefix matching or substring inclusion so tests remain reliable across different Chrome versions. Note: this is a followup of https://github.com/odoo/odoo/pull/285591 where I missed one occurence during forward-port. My bad. runbot-946570 Forward-Port-Of: odoo/odoo#288519
This fixes an automated point-of-sale test that could fail unpredictably when receipt printing produced an error on busy systems. The change prevents the screen from advancing too quickly, making test results more stable without changing the customer checkout experience.
Original PR description
The fast-payment tours with automatic receipt printing configure an unreachable printer to exercise the printing-failure path. Once the failed print settles, FeedbackScreen arms a 1500ms timer that auto-navigates to the next order (iface_print_auto). The tour needs to detect the resulting error dialog, confirm it, then click the validation button, all before that timer fires. On a fast machine this comfortably fits, but on a loaded CI runner the sequence can take longer than 1500ms, so the auto-navigation happens first, unmounting the feedback screen before the tour can click ".button.validation" and causing a step timeout that could not be reproduced locally. Click on the feedback screen background right after confirming the dialog to call stopAutomaticSkip() and cancel the pending timer, removing the race entirely. This mirrors the pattern already used in test_automatic_receipt_printing. runbot-946191 Forward-Port-Of: odoo/odoo#288403 Forward-Port-Of: odoo/odoo#284690
This fixes how the website builder handles links entered without a prefix, such as website addresses, email addresses, and phone numbers. Users will now get the expected link type automatically, reducing broken or incorrect links on images and social media fields.
Original PR description
Steps to reproduce: - Add an image and add a link on that image. - Set the URL input to "odoo.com". - Click outside the image and click on the image again. => The "http" protocol was added instead of "https". - Set the URL input to "test@test.com". - Click outside the image and click on the image again. => The "http" protocol was added instead of "mailto". The issue also occurs for phone numbers. The builder URL picker did not normalize entered URL values like the editor link popover does. Actions using the picker could therefore receive raw values and would need to normalized the URL in a different way. This commit reuses the editor link input normalization helper in the builder URL picker so committed and previewed URL values are handled consistently. task-6384411 Forward-Port-Of: odoo/odoo#286189 Forward-Port-Of: odoo/odoo#275936
Asset depreciation models are now labeled by the time needed to fully depreciate an asset instead of by a rate percentage. This makes model names easier to understand and fixes broken wording in translated languages by removing an English-only plural ending.
Original PR description
This commit does 2 things: 1. Rate-based models were named after their rate, e.g. "2.78% per Month". Now they are named after the duration it takes to fully depreciate the asset. For example "2.78% per Month" now reads "36 Month". A helper function was added to handle the rounding of the method number. 2. Also the plural 's' that was appended to the duration was removed. It was added onto the end of the translated period label, so it produced broken names in every language other than English. task-6498452
The call settings menu now shows the correct name for the selected audio output device when microphone and speaker devices share the same system ID. This prevents confusion for users checking or changing their call audio settings, especially in Chrome setups with default devices.
Original PR description
Steps to reproduce: - Have an input audio device and an output audio device with different names but same device ID. Using Chrome, if the OS only sees one of each, both should have "default" as device ID. (alternatively, modify the code at `updateDevicesList` to simulate having devices of that kind). - Select those devices in the call settings UI, then open the settings UI dropdown again. => The "input" device is properly shown but the "output" device shows the "input" device names (while in fact this is the right one selected in the inner dropdown). This happens since [1]. Before that there were native `<select>` nodes that filtered devices by kind before rendering each option, and the "default" value of Chrome was not really handled. [1]: https://github.com/odoo/odoo/commit/93d0931fba1f467de265200b6a0463cf7edf9534 Related to task-6533808 Forward-Port-Of: odoo/odoo#288285
This fixes a form issue where Save and Discard buttons could remain visible even after there was nothing left to save. Users who retype an equivalent value, such as a differently formatted number, will now see the form return to a clean state correctly.
Original PR description
**Description of the issue/feature this PR addresses:** Fixes #287978 In `useInputField` (`input_field_hook.js`), `onChange` and `commitChanges` only trigger the `FIELD_IS_DIRTY` bus event with…
**Description of the issue/feature this PR addresses:** Fixes #287978 In `useInputField` (`input_field_hook.js`), `onChange` and `commitChanges` only trigger the `FIELD_IS_DIRTY` bus event with `false` when the newly typed value actually differs from the value already stored on the record. When the typed text parses to the *same* value as what is already on the record (e.g. retyping `6,250` after the field already holds `6,25`), the code takes the `else` branch, which only resets the displayed text and never notifies the bus that the field is no longer dirty. `form_status_indicator.js` keeps whatever `fieldIsDirty` state it last received from that bus event, and shows the Save/Discard buttons whenever `root.dirty || fieldIsDirty`. Since nothing ever fires `FIELD_IS_DIRTY(false)` in that `else` branch, `fieldIsDirty` stays stuck at `true`. `Discard` correctly resets `root.dirty`, but has no way to reset `fieldIsDirty`, so the Save/Discard buttons keep showing even though the record is clean. **Current behavior before PR:** 1. Edit a field to a new value, click away (value committed, indicator shows Save/Discard as expected). 2. Edit the same field again, this time typing different text that parses to the *same* value (e.g. `1.20` when the field already holds `1.2`), click away. 3. Click **Discard**. The record is reverted, but the Save/Discard buttons remain visible. They stay stuck until the page is reloaded. **Desired behavior after PR is merged:** Retyping different text that parses to the same value clears the field's dirty state like any other case where the field ends up unchanged, so Discard (or any other action) correctly hides the Save/Discard buttons once there is nothing left to save. Forward-Port-Of: odoo/odoo#288030
The QFPay point-of-sale payment test was updated to match the current checkout flow, where staff must press Send before the terminal payment starts. This prevents the automated test from timing out and helps keep payment terminal validation reliable.
Original PR description
Commit 7a208335fa84 ("[IMP] point_of_sale: avoid fast payments") removed the automatic sending of the transaction to the terminal, so the user now has to click on "Send" to trigger the payment request.
The tours of the other payment terminals (adyen, razorpay, safaricom, viva_com) were adapted accordingly, but pos_qfpay was missed. As a result, the payment line never reaches the 'waitingCard' status and the tour times out waiting for the "Waiting for card" step.
Add the missing PaymentScreen.clickSendButton() step to fix the tour.
runbot-940270
Forward-Port-Of: odoo/odoo#275204