diff --git a/src/web/HTMLIngredient.mjs b/src/web/HTMLIngredient.mjs
index 91cbed891d..9f61b75a3b 100755
--- a/src/web/HTMLIngredient.mjs
+++ b/src/web/HTMLIngredient.mjs
@@ -166,6 +166,7 @@ class HTMLIngredient {
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
+ data-target="${this.target}"
${this.disabled ? "disabled" : ""}>`;
for (i = 0; i < this.value.length; i++) {
if ((m = this.value[i].name.match(/\[([a-z0-9 -()^]+)\]/i))) {
diff --git a/src/web/waiters/RecipeWaiter.mjs b/src/web/waiters/RecipeWaiter.mjs
index 4272ef3b67..e4198cd5a5 100755
--- a/src/web/waiters/RecipeWaiter.mjs
+++ b/src/web/waiters/RecipeWaiter.mjs
@@ -487,11 +487,19 @@ class RecipeWaiter {
* @param {HTMLElement} op
*/
triggerArgEvents(op) {
- // Trigger populateOption and argSelector events
+ // Trigger argSelector events and populateOption events only where the target is empty.
+ // When loading a saved recipe, arguments are populated before this method is called, so
+ // re-triggering populateOption events would overwrite saved custom values with defaults.
+ const args = op.querySelectorAll(".arg");
const triggerableOptions = op.querySelectorAll(".populate-option, .arg-selector");
const evt = new Event("change", {bubbles: true});
+
if (triggerableOptions.length) {
for (const el of triggerableOptions) {
+ if (el.classList.contains("populate-option")) {
+ const target = args[el.getAttribute("data-target")];
+ if (target && target.value !== "") continue;
+ }
el.dispatchEvent(evt);
}
}
diff --git a/tests/browser/03_recipe_load.js b/tests/browser/03_recipe_load.js
new file mode 100644
index 0000000000..58609d99ef
--- /dev/null
+++ b/tests/browser/03_recipe_load.js
@@ -0,0 +1,48 @@
+/**
+ * Regression tests for recipe loading behaviour.
+ *
+ * @author C85297 [95289555+C85297@users.noreply.github.com]
+ * @copyright Crown Copyright
+ * @license Apache-2.0
+ */
+
+const utils = require("./browserUtils.js");
+
+module.exports = {
+ before: browser => {
+ browser
+ .resizeWindow(1280, 800)
+ .url(browser.launchUrl)
+ .useCss()
+ .waitForElementNotPresent("#preloader", 10000);
+ },
+
+ "Recipe load preserves populated arguments": browser => {
+ const inputFormat = "HH:mm:ss a MMM DD, YYYY ";
+ const input = "10:20:30 pm Sep 26, 2019 ";
+
+ utils.loadRecipe(
+ browser,
+ "Translate DateTime Format",
+ input,
+ [
+ "Standard date and time",
+ inputFormat,
+ "UTC",
+ "DD/MM/YYYY HH:mm:ss",
+ "UTC"
+ ]
+ );
+
+ browser.execute(() => {
+ return Array.from(document.querySelectorAll("#rec-list li.operation .arg"))
+ .map(arg => arg.value);
+ }, [], function({value}) {
+ browser.expect(value[1]).to.equal(inputFormat);
+ });
+ },
+
+ after: browser => {
+ browser.end();
+ }
+};