diff --git a/e2e/calculate-linked-params.e2e-spec.ts b/e2e/calculate-linked-params.e2e-spec.ts
index 12e68d423b9cdda3373f74cabd60824086cfb91e..7c54f5af436fb313519b1919e95a5a6a923afd8a 100644
--- a/e2e/calculate-linked-params.e2e-spec.ts
+++ b/e2e/calculate-linked-params.e2e-spec.ts
@@ -5,6 +5,7 @@ import { Navbar } from "./navbar.po";
 import { SideNav } from "./sidenav.po";
 import { browser, by } from "protractor";
 import { PreferencesPage } from "./preferences.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Uses an example configuration to calculate :
@@ -62,7 +63,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y, "link");
         const sel = await calcPage.getLinkedValueSelect(Y);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
@@ -79,7 +80,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y, "link");
         const sel = await calcPage.getLinkedValueSelect(Y);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
         // vary W
         const W = calcPage.getInputById("W");
         await calcPage.setParamMode(W, "var");
@@ -102,7 +103,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
@@ -122,7 +123,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
@@ -142,7 +143,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
         // vary W
         const W = calcPage.getInputById("W");
         await calcPage.setParamMode(W, "var");
@@ -168,7 +169,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts
index af1e1803ce378ba967def9837500ece6da58a434..12c5a8de42cace9dad88a7905d233e0091842aeb 100644
--- a/e2e/calculator.po.ts
+++ b/e2e/calculator.po.ts
@@ -331,13 +331,6 @@ export class CalculatorPage {
         return calcButton;
     }
 
-    async changeSelectValue(elt: ElementFinder, index: number) {
-        await elt.click();
-        const optionId = ".cdk-overlay-container mat-option:nth-of-type(" + (index + 1) + ")";
-        const option = element(by.css(optionId));
-        await option.click();
-    }
-
     // find parent element of elt having class "container"
     async findParentContainer(elt: ElementFinder): Promise<ElementFinder> {
         let i = 8; // garde fous
diff --git a/e2e/cloisons.e2e-spec.ts b/e2e/cloisons.e2e-spec.ts
index 2febdc57e4263fb9d97e1466736b8e2699942cf9..f251afabc8b8c7d4c8c81773ea3c8bcc8c56d277 100644
--- a/e2e/cloisons.e2e-spec.ts
+++ b/e2e/cloisons.e2e-spec.ts
@@ -3,6 +3,7 @@ import { CalculatorPage } from "./calculator.po";
 import { browser } from "protractor";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Cloisons - différents tests qui n'ont pas tant de rapport que ça avec les cloisons :)
@@ -44,7 +45,7 @@ describe("ngHyd − cloisons", () => {
         await browser.sleep(300);
 
         // 4. change LoiDebit
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_loidebit"), 1);
+        await changeSelectValue(calcPage.getSelectById("select_loidebit"), 1);
         await browser.sleep(300);
 
         // 5. check number of inputs in CALC mode
diff --git a/e2e/clone-calc.e2e-spec.ts b/e2e/clone-calc.e2e-spec.ts
index 038a90e661a28a6526a9b143f407842f3bed4329..a63f565b0fb43630cb3c5f88fb4b91926629e528 100644
--- a/e2e/clone-calc.e2e-spec.ts
+++ b/e2e/clone-calc.e2e-spec.ts
@@ -4,7 +4,7 @@ import { CalculatorPage } from "./calculator.po";
 import { Navbar } from "./navbar.po";
 import { browser } from "protractor";
 import { PreferencesPage } from "./preferences.po";
-import { scrollPageToTop } from "./util.po";
+import { changeSelectValue, scrollPageToTop } from "./util.po";
 
 /**
  * Clone calculators
@@ -54,7 +54,7 @@ describe("ngHyd − clone a calculator", () => {
             k: 0.6,
             Ks: 42
         };
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
+        await changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
         await calcPage.getInputById("k").clear();
         await calcPage.getInputById("k").sendKeys(sourceValues["k"]);
         await calcPage.getInputById("Ks").clear();
@@ -63,7 +63,7 @@ describe("ngHyd − clone a calculator", () => {
         const debitSP = calcPage.getInputById("Q");
         await calcPage.setParamMode(debitSP, "link");
         await browser.sleep(500);
-        await calcPage.changeSelectValue(calcPage.getSelectById("linked_Q"), 1); // "Courbe de remous"
+        await changeSelectValue(calcPage.getSelectById("linked_Q"), 1); // "Courbe de remous"
         await browser.sleep(500);
 
         // otherwise clickCloneCalcButton() fails with "Element is not clickable at point"
diff --git a/e2e/examples-empty-fields.e2e-spec.ts b/e2e/examples-empty-fields.e2e-spec.ts
index 08f40c467f44678244027dbcd7487e56c16dc6aa..3a8d3942cd6594c7bc3e367d9128597809980e77 100644
--- a/e2e/examples-empty-fields.e2e-spec.ts
+++ b/e2e/examples-empty-fields.e2e-spec.ts
@@ -3,6 +3,7 @@ import { CalculatorPage } from "./calculator.po";
 import { ListPage } from "./list.po";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po"
+import { changeSelectValue } from "./util.po";
 
 /**
  * check that fields are empty on creation
@@ -60,7 +61,7 @@ describe("ngHyd - Check that examples fields are not empty with 'empty fields on
 
         // modify 1st structure discharge law
         const dischargeSelect = calcPage.getSelectById("select_loidebit");
-        await calcPage.changeSelectValue(dischargeSelect, 1);
+        await changeSelectValue(dischargeSelect, 1);
         await browser.sleep(200);
 
         // open initial dialog
diff --git a/e2e/lechapt-calmon.e2e-spec.ts b/e2e/lechapt-calmon.e2e-spec.ts
index 91dea3194e5d9ffa11790e9d417080e556ea8ab2..f3be14a59a0fde635a339a8cc469c8048ffb23a5 100644
--- a/e2e/lechapt-calmon.e2e-spec.ts
+++ b/e2e/lechapt-calmon.e2e-spec.ts
@@ -3,6 +3,7 @@ import { browser, by } from "protractor";
 import { CalculatorPage } from "./calculator.po";
 import { PreferencesPage } from "./preferences.po";
 import { Navbar } from "./navbar.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Check that created/cloned structures have empty fields when
@@ -45,7 +46,7 @@ describe("Lechapt&Calmon - ", () => {
 
         // select last material type
         const materialSelect = calcPage.getSelectById("select_material");
-        await calcPage.changeSelectValue(materialSelect, 8);
+        await changeSelectValue(materialSelect, 8);
         await browser.sleep(200);
 
         // run calculation
@@ -58,7 +59,7 @@ describe("Lechapt&Calmon - ", () => {
         const pl1 = await res1.all(by.css("td")).get(1).getText();
 
         // select first material type
-        await calcPage.changeSelectValue(materialSelect, 0);
+        await changeSelectValue(materialSelect, 0);
         await browser.sleep(200);
 
         // run calculation
diff --git a/e2e/linked-parameter-section-type.e2e-spec.ts b/e2e/linked-parameter-section-type.e2e-spec.ts
index b42c13d0f8ad8249514e3880592938bd726888bb..a863f273ed3f66ba5c4e19eeb2f14b02e2fd5134 100644
--- a/e2e/linked-parameter-section-type.e2e-spec.ts
+++ b/e2e/linked-parameter-section-type.e2e-spec.ts
@@ -3,6 +3,7 @@ import { ListPage } from "./list.po";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po";
 import { CalculatorPage } from "./calculator.po";
+import { changeSelectValue } from "./util.po";
 
 describe("linked parameter in calculator with section - ", () => {
     let listPage: ListPage;
@@ -42,7 +43,7 @@ describe("linked parameter in calculator with section - ", () => {
         await calcPage.setParamMode(inputQ, "link");
 
         // change section type
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
+        await changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
 
         // check Q is still in linked mode
         expect(await calcPage.inputIsInLinkedMode(inputQ)).toBe(true);
diff --git a/e2e/load-save-session.e2e-spec.ts b/e2e/load-save-session.e2e-spec.ts
index 436058e6f6ffc4d54e716b1680c22b6b8dc9de18..8689c6f13a7510026cff21608aefa1ff663ee5cd 100644
--- a/e2e/load-save-session.e2e-spec.ts
+++ b/e2e/load-save-session.e2e-spec.ts
@@ -5,7 +5,7 @@ import { Navbar } from "./navbar.po";
 import { SideNav } from "./sidenav.po";
 import { browser, by, element } from "protractor";
 import { PreferencesPage } from "./preferences.po";
-import { expectNumber } from "./util.po";
+import { changeSelectValue, expectNumber } from "./util.po";
 
 const fs = require("fs");
 const path = require("path");
@@ -122,7 +122,7 @@ describe("ngHyd − save and load sessions", () => {
         await listPage.clickMenuEntryForCalcType(2); // Section paramétrée
         await browser.sleep(500);
 
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 2); // mode "trapezoidal"
+        await changeSelectValue(calcPage.getSelectById("select_section"), 2); // mode "trapezoidal"
 
         await calcPage.getInputById("Ks").clear(); // coefficient de Strickler
         await browser.sleep(1000);
@@ -190,7 +190,7 @@ describe("ngHyd − save and load sessions", () => {
 
                         // select next select option (optionally looping)
                         const nextInd = (ind + 1) % optionCount;
-                        await calcPage.changeSelectValue(sel, nextInd);
+                        await changeSelectValue(sel, nextInd);
                         await browser.sleep(200);
 
                         // save session
diff --git a/e2e/ouvrages-empty-fields.e2e-spec.ts b/e2e/ouvrages-empty-fields.e2e-spec.ts
index 4a28316f8c5a2001f778241fd31c211da1d00fec..918107e2c8a980f573a5cced40dbfe6dbfa2ed67 100644
--- a/e2e/ouvrages-empty-fields.e2e-spec.ts
+++ b/e2e/ouvrages-empty-fields.e2e-spec.ts
@@ -4,6 +4,7 @@ import { CalculatorPage } from "./calculator.po";
 import { AppPage } from "./app.po";
 import { PreferencesPage } from "./preferences.po";
 import { Navbar } from "./navbar.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Check that created/cloned structures have empty fields when
@@ -51,7 +52,7 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
 
         // change 1st structure type to rectangular weir
         const structSelect = calcPage.getSelectById("select_structure");
-        await calcPage.changeSelectValue(structSelect, 1);
+        await changeSelectValue(structSelect, 1);
         await browser.sleep(200);
 
         // check 1st structure empty fields
@@ -91,7 +92,7 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
 
         // change 1st structure type to rectangular weir
         const structSelect = calcPage.getSelectById("select_structure");
-        await calcPage.changeSelectValue(structSelect, 1);
+        await changeSelectValue(structSelect, 1);
         await browser.sleep(200);
 
         // copy structure
@@ -102,7 +103,7 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
         // change 2nd structure type to rectangular gate
         const selects = await element.all(by.css("mat-select#select_structure"));
         const structSelect2 = selects[1];
-        await calcPage.changeSelectValue(structSelect2, 5);
+        await changeSelectValue(structSelect2, 5);
         await browser.sleep(200);
 
         // check empty fields
@@ -135,12 +136,12 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
 
         // change 1st structure type to rectangular weir
         const structSelect = calcPage.getSelectById("select_structure");
-        await calcPage.changeSelectValue(structSelect, 1);
+        await changeSelectValue(structSelect, 1);
         await browser.sleep(200);
 
         // change discharge law to Larinier
         const dischargeSelect = calcPage.getSelectById("select_loidebit");
-        await calcPage.changeSelectValue(dischargeSelect, 3);
+        await changeSelectValue(dischargeSelect, 3);
         await browser.sleep(200);
 
         // check empty fields
diff --git a/e2e/pab.e2e-spec.ts b/e2e/pab.e2e-spec.ts
index 866f67fb57da855a5c8ce10d407efd3da5616ffc..edcdd97504ef4be2502413318d40266a8680beb5 100644
--- a/e2e/pab.e2e-spec.ts
+++ b/e2e/pab.e2e-spec.ts
@@ -5,7 +5,7 @@ import { browser, by, element } from "protractor";
 import { AppPage } from "./app.po";
 import { SideNav } from "./sidenav.po";
 import { PreferencesPage } from "./preferences.po";
-import { scrollPageToTop } from "./util.po";
+import { changeSelectValue, scrollPageToTop } from "./util.po";
 
 /**
  * Clone calculators
@@ -297,7 +297,7 @@ describe("ngHyd − Passe à Bassins", () => {
 
             // change iteration
             const pve = calcPage.getSelectById("pab-variating-element");
-            calcPage.changeSelectValue(pve, 3);
+            await changeSelectValue(pve, 3);
             await browser.sleep(300);
             // check absence of logs
             expect(await calcPage.nbLogEntries()).toBe(2);
diff --git a/e2e/preferences.po.ts b/e2e/preferences.po.ts
index 264ebb84fdc7f9ab570bb8524e7f61ccd26adb02..51c1fc8de32868ef5d25ca5da6c44443e26fadcb 100644
--- a/e2e/preferences.po.ts
+++ b/e2e/preferences.po.ts
@@ -1,4 +1,5 @@
 import { browser, by, element, ElementFinder } from "protractor";
+import { changeSelectValue } from "./util.po";
 
 export class PreferencesPage {
     navigateTo() {
@@ -43,10 +44,7 @@ export class PreferencesPage {
 
     async changeLanguage(index: number) {
         const select = this.getLanguageSelect();
-        await select.click();
-        const optionId = ".cdk-overlay-container mat-option#mat-option-" + index;
-        const option = element(by.css(optionId));
-        await option.click();
+        await changeSelectValue(select, index);
     }
 
     async enableEvilEmptyFields() {
diff --git a/e2e/pressure-loss-empty-fields.e2e-spec.ts b/e2e/pressure-loss-empty-fields.e2e-spec.ts
index c4516a88bdeeb74f95eed96b4897f2641dd4f6a5..59eb87c641d01eeae71004f1b2cd07b5523625a5 100644
--- a/e2e/pressure-loss-empty-fields.e2e-spec.ts
+++ b/e2e/pressure-loss-empty-fields.e2e-spec.ts
@@ -3,6 +3,7 @@ import { Navbar } from "./navbar.po";
 import { browser } from "protractor";
 import { CalculatorPage } from "./calculator.po";
 import { PreferencesPage } from "./preferences.po";
+import { changeSelectValue } from "./util.po";
 
 describe("Check fields are empty in 'pressure loss' calculator when created with 'empty fields' option -", () => {
     let listPage: ListPage;
@@ -32,7 +33,7 @@ describe("Check fields are empty in 'pressure loss' calculator when created with
 
         // select Lechapt-Calmon pressure loss law
         const materialSelect = calcPage.getSelectById("select_pressurelosstype");
-        await calcPage.changeSelectValue(materialSelect, 0);
+        await changeSelectValue(materialSelect, 0);
         await browser.sleep(200);
 
         expect(calcPage.checkEmptyOrFilledFields(["Q", "D", "Lg", "Kloc"], [true, true, true, true]));
diff --git a/e2e/remous.e2e-spec.ts b/e2e/remous.e2e-spec.ts
index d13ccd48bd73cfea28a4b94f39b7243579f7b073..342d35edb63c03d52c0d0b8a60c86fcc00730d2d 100644
--- a/e2e/remous.e2e-spec.ts
+++ b/e2e/remous.e2e-spec.ts
@@ -4,6 +4,7 @@ import { browser } from "protractor";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po";
 import { SideNav } from "./sidenav.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Remous
@@ -59,7 +60,7 @@ describe("ngHyd − remous", () => {
         await browser.sleep(300);
 
         // 2. Set to trapezoidal section with bank slope of 2m/m and 20 meter width bed
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 2);
+        await changeSelectValue(calcPage.getSelectById("select_section"), 2);
         await browser.sleep(300);
         await calcPage.getInputById("LargeurFond").clear();
         await browser.sleep(300);
diff --git a/e2e/solveur.e2e-spec.ts b/e2e/solveur.e2e-spec.ts
index 89ca70d6ed4b357ddf9999ae61b08f9b4c4e5a9c..afe88721eb9b32753d9db0ec05fb40e0727c0a82 100644
--- a/e2e/solveur.e2e-spec.ts
+++ b/e2e/solveur.e2e-spec.ts
@@ -5,7 +5,7 @@ import { Navbar } from "./navbar.po";
 import { browser, by, element } from "protractor";
 import { SideNav } from "./sidenav.po";
 import { PreferencesPage } from "./preferences.po";
-import { scrollPageToTop } from "./util.po";
+import { changeSelectValue, scrollPageToTop } from "./util.po";
 
 /**
  * Clone calculators
@@ -76,7 +76,7 @@ describe("Solveur - ", () => {
         expect(hasResults).toBe(true);
 
         // change targetted Nub, check that targetted result changes too
-        await calcPage.changeSelectValue(ntc, 0);
+        await changeSelectValue(ntc, 0);
         const nttV2 = await calcPage.getSelectValueText(ntt);
         expect(nttV2).not.toContain("Puissance dissipée (PV)");
     });
@@ -111,9 +111,9 @@ describe("Solveur - ", () => {
         // Go back to Solveur
         await navbar.clickCalculatorTab(0);
 
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_target_nub"), 1); // "Puissance / PV"
+        await changeSelectValue(calcPage.getSelectById("select_target_nub"), 1); // "Puissance / PV"
         await browser.sleep(500);
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_searched_param"), 2); // "Chute / Z2"
+        await changeSelectValue(calcPage.getSelectById("select_searched_param"), 2); // "Chute / Z2"
         await browser.sleep(500);
         await calcPage.getInputById("Ytarget").sendKeys("318");
 
@@ -159,7 +159,7 @@ describe("Solveur - ", () => {
 
         // modify searched parameter
         const sel = calcPage.getSelectById("select_searched_param");
-        await calcPage.changeSelectValue(sel, 11);
+        await changeSelectValue(sel, 11);
         await browser.sleep(300);
         const selText = await calcPage.getSelectValueText(sel);
 
diff --git a/e2e/util.po.ts b/e2e/util.po.ts
index e772a28ce9c01e0c54f85d0bce84a01df90e7ac5..aded71c166c96b6914bff75af3f3fa4fe409185f 100644
--- a/e2e/util.po.ts
+++ b/e2e/util.po.ts
@@ -1,4 +1,4 @@
-import { ElementFinder, browser } from "protractor";
+import { ElementFinder, browser, by, element } from "protractor";
 
 /**
  * scroll page to make element visible
@@ -27,3 +27,11 @@ export function expectNumber(msg: string, val: number, expected: number) {
     }
     expect(val).toEqual(expected);
 }
+
+export async function changeSelectValue(elt: ElementFinder, index: number) {
+    await elt.click();
+    const optionId = ".cdk-overlay-container mat-option:nth-of-type(" + (index + 1) + ")";
+    const option = element(by.css(optionId));
+    await option.click();
+    await browser.sleep(200);
+}