diff --git a/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts b/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts
index 9edcdbb3a95..07fdfb9db79 100644
--- a/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts
+++ b/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts
@@ -103,7 +103,7 @@ describe("InsertAutofillContentService", () => {
delay_between_operations: 20,
},
metadata: {},
- autosubmit: null,
+ autosubmit: [],
savedUrls: ["https://bitwarden.com"],
untrustedIframe: false,
itemType: "login",
@@ -218,28 +218,21 @@ describe("InsertAutofillContentService", () => {
await insertAutofillContentService.fillForm(fillScript);
- expect(insertAutofillContentService["userCancelledInsecureUrlAutofill"]).toHaveBeenCalled();
- expect(
- insertAutofillContentService["userCancelledUntrustedIframeAutofill"],
- ).toHaveBeenCalled();
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenCalledTimes(3);
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
1,
fillScript.script[0],
0,
- fillScript.script,
);
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
2,
fillScript.script[1],
1,
- fillScript.script,
);
expect(insertAutofillContentService["runFillScriptAction"]).toHaveBeenNthCalledWith(
3,
fillScript.script[2],
2,
- fillScript.script,
);
});
});
@@ -623,14 +616,12 @@ describe("InsertAutofillContentService", () => {
});
});
- it("will set the `value` attribute of any passed input or textarea elements", () => {
- document.body.innerHTML = ``;
+ it("will set the `value` attribute of any passed input or textarea elements if the value differs", () => {
+ document.body.innerHTML = ``;
const value1 = "test";
const value2 = "test2";
const textInputElement = document.getElementById("username") as HTMLInputElement;
- textInputElement.value = value1;
const textareaElement = document.getElementById("bio") as HTMLTextAreaElement;
- textareaElement.value = value2;
jest.spyOn(insertAutofillContentService as any, "handleInsertValueAndTriggerSimulatedEvents");
insertAutofillContentService["insertValueIntoField"](textInputElement, value1);
@@ -647,6 +638,45 @@ describe("InsertAutofillContentService", () => {
insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
).toHaveBeenCalledWith(textareaElement, expect.any(Function));
});
+
+ it("will NOT set the `value` attribute of any passed input or textarea elements if they already have values matching the passed value", () => {
+ document.body.innerHTML = ``;
+ const value1 = "test";
+ const value2 = "test2";
+ const textInputElement = document.getElementById("username") as HTMLInputElement;
+ textInputElement.value = value1;
+ const textareaElement = document.getElementById("bio") as HTMLTextAreaElement;
+ textareaElement.value = value2;
+ jest.spyOn(insertAutofillContentService as any, "handleInsertValueAndTriggerSimulatedEvents");
+
+ insertAutofillContentService["insertValueIntoField"](textInputElement, value1);
+
+ expect(textInputElement.value).toBe(value1);
+ expect(
+ insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
+ ).not.toHaveBeenCalled();
+
+ insertAutofillContentService["insertValueIntoField"](textareaElement, value2);
+
+ expect(textareaElement.value).toBe(value2);
+ expect(
+ insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
+ ).not.toHaveBeenCalled();
+ });
+
+ it("skips filling when the field already has the target value", () => {
+ const value = "test";
+ document.body.innerHTML = ``;
+ const element = document.getElementById("username") as FillableFormFieldElement;
+ jest.spyOn(insertAutofillContentService as any, "handleInsertValueAndTriggerSimulatedEvents");
+
+ insertAutofillContentService["insertValueIntoField"](element, value);
+
+ expect(
+ insertAutofillContentService["handleInsertValueAndTriggerSimulatedEvents"],
+ ).not.toHaveBeenCalled();
+ expect(element.value).toBe(value);
+ });
});
describe("handleInsertValueAndTriggerSimulatedEvents", () => {
diff --git a/apps/browser/src/autofill/services/insert-autofill-content.service.ts b/apps/browser/src/autofill/services/insert-autofill-content.service.ts
index 6034563a947..9ddbcdc005d 100644
--- a/apps/browser/src/autofill/services/insert-autofill-content.service.ts
+++ b/apps/browser/src/autofill/services/insert-autofill-content.service.ts
@@ -49,8 +49,9 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
return;
}
- const fillActionPromises = fillScript.script.map(this.runFillScriptAction);
- await Promise.all(fillActionPromises);
+ for (let index = 0; index < fillScript.script.length; index++) {
+ await this.runFillScriptAction(fillScript.script[index], index);
+ }
}
/**
@@ -189,10 +190,14 @@ class InsertAutofillContentService implements InsertAutofillContentServiceInterf
const elementCanBeReadonly =
elementIsInputElement(element) || elementIsTextAreaElement(element);
const elementCanBeFilled = elementCanBeReadonly || elementIsSelectElement(element);
+ const elementValue = (element as HTMLInputElement)?.value || element?.innerText || "";
+
+ const elementAlreadyHasTheValue = !!(elementValue?.length && elementValue === value);
if (
!element ||
!value ||
+ elementAlreadyHasTheValue ||
(elementCanBeReadonly && element.readOnly) ||
(elementCanBeFilled && element.disabled)
) {